js自定義滾動條外掛
阿新 • • 發佈:2019-02-07
知識點
- $.extend 方法
- jQuery 事件名稱空間
- 事件物件屬性 : pageX 、 pageY
- 獲得原生事件 : e.originalEvent
- 位置方法 : scrollTop、scrollLeft、scrollHeight、scrollWidth 、position
- 滾輪事件的處理 :oEv.wheelDelta 、oEv.deltail
原始碼地址
演示地址
js
(function(win,doc,$){
// 建構函式
function CusScrollBar(options){
this._init(options);
}
// 擴充套件原型物件
$.extend(CusScrollBar.prototype,{
// 初始化
_init:function(options){
var self=this;
// 預設配置
self.options={
scrollDir :"y", // 滾動方向
contSelector :"", // 滾動區域選擇器
barSelector :"", // 滾動條選擇器
sliderSelector :"" , // 滾動滑塊選擇器
wheelStep :10, // 滾輪步長 ,預設為10
tabItemSelector:"", // 標籤類名
tabActiveClass :"", // 選中類名
anchorSelector :"", // 錨點選擇器
correctSelector:"", // 校正元素
articalSelector:"", // 文章選擇器
isAnimate :false , // 是否開啟動畫 ,預設無動畫
speed :800, // 動畫時長
}
$.extend(true,self.options,options || {});
self._initDomEvent();
return self;
},
// 初始化dom元素
_initDomEvent:function(){
var opts=this.options;
// 滾動區域
this.$cont=$(opts.contSelector);
// 滾動條
this.$slider=$(opts.sliderSelector);
// 滑塊
this.$bar=opts.barSelector ? $(opts.barSelector) : self.$slider.parent();
// 文件物件
this.$doc=$(doc);
// 標籤項
this.$tabItem=$(opts.tabItemSelector);
// 錨點項
this.$anchor=$(opts.anchorSelector);
// 文章
this.$article=$(opts.articalSelector);
// 校正元素物件
this.$correct=$(opts.correctSelector);
// 啟動函式
this._initSliderDragEvent()
._bindContScroll()
._bindMouseWheel()
._initTabEvent()
.initArticleHeight();
},
// 初始化滑塊拖動功能
_initSliderDragEvent:function(self){
var slider=this.$slider,
sliderEl=slider[0],
self=this;
if(sliderEl){
var doc=this.$doc,
dragStratPagePosition,
dragStartScrollPosition,
dragContBarRate;
function mousemoveHandler (e){
e.preventDefault;
console.log("mousemove");
if(dragStratPagePosition == null){
return;
}
// 滑鼠按下 到 移動到當前位置 之間的距離
var dis=e.pageY-dragStratPagePosition;
self.scrollTo(dragStartScrollPosition + dis*dragContBarRate);
}
slider.on("mousedown",function(e){
e.preventDefault();
console.log("mousedown");
dragStratPagePosition=e.pageY;
dragStartScrollPosition=self.$cont[0].scrollTop;
dragContBarRate=self.getMaxScrollPosition() / self.getMaxSliderPosition();+
doc.on("mousemove.scroll",mousemoveHandler).on("mouseup.scroll",function(e){
console.log("mouseup");
doc.off(".scroll");
});
});
}
return self;
},
// 監聽滑鼠滾輪 同步內容滾動
_bindMouseWheel:function(){
var self=this;
self.$cont.on("mousewheel DOMMouseScroll",function(e){
console.log("mousewheel");
e.preventDefault();
var oEv=e.originalEvent,
wheelRange=oEv.wheelDelta ? -oEv.wheelDelta/120 : (oEv.deltail || 0)/3;
self.scrollTo(self.$cont[0].scrollTop + wheelRange * self.options.wheelStep);
// console.log(wheelRange); // 1 / -1
});
return self;
},
// 監聽內容的滾動 ,同步滑塊的位置
_bindContScroll:function(){
var self=this;
self.$cont.on("scroll",function(){
var sliderEl=self.$slider[0];
if(sliderEl){
sliderEl.style.top=self.getSliderPosition() + "px";
}
});
return self;
},
// 標籤切換 、定位
_initTabEvent:function(){
var self=this;
self.$tabItem.on("click",function(e){
e.preventDefault();
var index=$(this).index();
self.changeTabSelect(index);
// 已經滾出可視區的高度 + 指定錨點與內容容器的距離
self.scrollTo(self.$cont[0].scrollTop +self.getAnchorPosition(index),self.options.isAnimate);
});
return self;
},
// 初始化文件高度
initArticleHeight:function(){
var self=this,
lastArticle=self.$article.last();
// 比較 最後一篇文章高度 和可視區高度
var lastArticleHeight=lastArticle.height(),
contHeight=self.$cont.height();
if(lastArticleHeight < contHeight){
self.$correct[0].style.height=contHeight -
lastArticleHeight-self.$anchor.outerHeight()+"px";
}
},
// 獲取錨點與父元素的距離
getAnchorPosition:function(index){
return this.$anchor.eq(index).position().top;
},
// 切換標籤的選中
changeTabSelect:function(index){
var self=this,
active=self.options.tabActiveClass;
return self.$tabItem.eq(index).addClass(active)
.siblings().removeClass(active);
},
// 計算滑塊當前的位置
getSliderPosition:function(){
var self=this;
var maxSliderPosition=self.getMaxSliderPosition();
// 內容區域滾動的比例
var disContRate=self.$cont[0].scrollTop/self.getMaxScrollPosition();
return Math.min(maxSliderPosition,maxSliderPosition * disContRate);
},
// 內容可滾動的高度
getMaxScrollPosition:function(){
var self=this;
return Math.max(self.$cont.height(),self.$cont[0].scrollHeight)-self.$cont.height();
},
// 滑塊可移動的距離
getMaxSliderPosition:function(){
var self=this;
return self.$bar.height() - self.$slider.height();
},
// 獲取每個錨點位置資訊的陣列
getAllAnchorPosition:function(){
var self=this,
allPositionArr=[];
for(var i=0;i<self.$anchor.length;i++){
allPositionArr.push(self.$cont[0].scrollTop + self.getAnchorPosition(i));
}
return allPositionArr;
},
// 設定滾動位置
scrollTo:function(positionVal,isAnimate){
var self=this;
var posArr=self.getAllAnchorPosition();
function getIndex(positionVal){
for(var i=posArr.length-1;i>=0;i--){
if(positionVal>=posArr[i]){
return i;
}else{
continue;
}
}
}
// 錨點數與標籤數相同
if(posArr.length == self.$tabItem.length){
self.changeTabSelect(getIndex(positionVal));
}
if(isAnimate){
self.$cont.animate({scrollTop:positionVal+"px"},self.options.speed);
console.log("animate:"+self.options.speed);
}else{
self.$cont.scrollTop(positionVal);
console.log("no animate");
}
}
});
win.CusScrollBar=CusScrollBar;
})(window,document,jQuery);
html
<div class="scroll">
<ul class="scroll-tab">
<li class="tab-item tab-active">春天來了</li>
<li class="tab-item">夏天來了</li>
<li class="tab-item">秋天來了</li>
<li class="tab-item">冬天來了</li>
</ul>
<div class="scroll-wrap">
<div class="scroll-content">
<h3 class="anchor">春天來了</h3>
<p class="scroll-ol">
...
<div class="correct-bot"></div>
</div>
<div class="scroll-bar">
<div class="scroll-slider"></div>
</div>
</div>
</div>
<script type="text/javascript" src="js/jquery.js" ></script>
<script type="text/javascript" src="js/scroll-bar.js" ></script>
<script type="text/javascript">
// 呼叫時注意 tabActiveClass :類名不帶 .
new CusScrollBar({
contSelector :".scroll-content", // 滾動區域選擇器
barSelector :".scroll-bar", // 滾動條選擇器
sliderSelector :".scroll-slider" , // 滾動滑塊選擇器
wheelStep :"10", // 滾輪步長
tabItemSelector:".tab-item", // 標籤項
tabActiveClass :"tab-active", // 選中類名 不帶.
anchorSelector :".anchor", // 錨點選擇器
correctSelector:".correct-bot", // 校正元素
articalSelector:".scroll-ol", // 文章選擇器
isAnimate :true, // true :開啟動畫 ,false:關閉動畫
speed :500 // 動畫時長
});
</script>
css
.body,html{
background:#ccc;
}
.scroll{
background:#fff;
width:500px;
height:auto;
margin:50px auto;
}
.scroll-tab{
width:100%;
height:auto;
background:#f5f4f4;
}
.scroll-tab .tab-item{
display:inline-block;
line-height:25px;
text-align:center;
font-size:16px;
padding:3px 10px;
cursor:pointer;
}
.scroll-tab .tab-item.tab-active{
background:#fff;
color:lightseagreen;
border-top:2px solid lightseagreen;
margin-top:-2px;
}
.scroll-wrap{
position:relative;
width:100%;
height:300px;
}
// 設定內容區域 與父元素同高, 超出隱藏
.scroll-wrap .scroll-content{
width:90%;
height:100%;
overflow:hidden;
margin:0 auto;
}
.scroll-content .anchor{
text-align:center;
font-size:20px;
font-weight: bold;
line-height: 50px;
}
.scroll-wrap .scroll-bar{
position:absolute;
top:0px;
right:0px;
height:100%;
width:15px;
background:#e0dede;
}
.scroll-wrap .scroll-slider{
position:absolute;
height:50px;
width:100%;
background:lightseagreen;
cursor:pointer;
}