1. 程式人生 > >js自定義滾動條外掛

js自定義滾動條外掛

知識點
  • $.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;
}