效果圖:
這篇文章主要講解js交互,就不用篇幅去告訴大家怎么寫html css了,讓文章言簡意賅。
大體思路:
如何實現滾動滑塊,讓滑塊與內容一起聯動呢?請看下圖:
首先來看,
空心鼠標位置與實心鼠標位置的距離 是不是等於滑塊移動的距離X0 呢?
答:等於
滑塊移動的最大距離X0是多少呢?
答:滾動條的高度X - 滑塊的高度
內容能滾動最大高度Y0是多少呢?
答:內容總高度Y - 內容可視區的高度
通過比較:可以得出滾動比率:
那么代碼應該怎么寫呢:
第一步: 獲取鼠標移動距離 = 滑塊移動距離
第二步: 獲取滑塊可移動的距離
第三步: 內容可滾動的高度
第四步: 通過上面的滾動比例關系可以獲取內容滾動高度
最五步:設置滑塊的位置
插件封裝大框:
- 首先創建一個構造函數CusScrollBar
- 然后通過new操作符實例化這個構造函數,並調用初始化函數_init,_init是這個實例初始化的入口。
補充:(自調用匿名函數:通過創建一個自調用匿名函數,創建一個特殊的函數作用域,該作用域中的代碼不會和已有的同名函數、方法和變量以及第三方庫發生沖突。)
- win,doc,$: 對應外部傳過來的window對象,document對象,jQuery對象。
- CusScrollBar: 創建一個構造函數,並調用初始化函數_init()。
- [options]: 實例化參數傳入到_init函數中
- this: 代表實例
原型上添加方法:
方案1:
CusScrollBar.prototype._init = function () { console.log("test"); }
方案2: (基於jquery的extend方法)
$.extend(CusScrollBar.prototype, {
A: function () {}, B: function () {} })
補充:$.extend方法 :
暴露構造函數,使外部可調用:
win.CusScrollBar = CusScrollBar;
上面的大框講解完成了,下面開始講解原型上定義的方法:
_init()函數:
1 _init: function (options) { 2 // 保存外部的this 這里的this =》 CusScrollBar 3 var self = this; 4 // 配置默認參數 5 self.options = { 6 scrollDir: 'y', // 滾動的方向 7 contSelector: '', // 滾動內容區選擇器 8 barSelector: '', // 滾動條選擇器 9 sliderSelector: '', // 滾動滑塊兒選擇器 10 correctSelector: '.correct-bot', // 矯正元素 11 }; 12 // 通過深拷貝將外部參數與默認參數合並 13 $.extend(true, self.options, options || {}); 14 // 調用_initDomEvent方法 15 self._initDomEvent(); 16 // 返回self,實現鏈式調用 17 return self; 18 },
_initDomEvent()函數:
1 _initDomEvent: function () { 2 var opts = this.options; 3 // 滾動內容區對象,必須填 4 this.$cont = $(opts.contSelector); 5 // 滾動條滑塊對象,必須填 6 this.$slider = $(opts.sliderSelector); 7 // 滾動條對象 8 this.$bar = opts.barSelector ? 9 $(opts.barSelector) : 10 self.$slider.parent(); 11 // 獲取文檔對象 12 this.$doc = $(doc); 13 // 矯正元素對象 14 this.$correct = $(opts.correctSelector); 15 this._initSliderDragEvent() 16 ._bindContScroll(); 17 },
_initSliderDragEvent()函數
1 _initSliderDragEvent: function () { 2 var slider = this.$slider, 3 sliderEl = slider[0], 4 self = this; 5 if (sliderEl) { 6 var doc = this.$doc, 7 // 拖動起始位置 8 dragStartPagePosition, 9 // 10 dragStartScrollPosition, 11 // 拖動比例 12 dragContBarRate; 13 14 function mousemoveHandler(e) { 15 e.preventDefault(); 16 console.log('mousemove'); 17 if (dragStartPagePosition == null) return; 18 self.scrollTo( 19 dragStartScrollPosition + 20 (e.pageY - dragStartPagePosition) * dragContBarRate 21 ); 22 } 23 24 // 綁定事件 25 slider.on('mousedown', function (e) { 26 // 阻止瀏覽器默認行為 27 e.preventDefault(); 28 console.log('mousedown'); 29 dragStartPagePosition = e.pageY; 30 dragStartScrollPosition = self.$cont[0].scrollTop; 31 dragContBarRate = 32 self.getMaxScrollPosition() / self.getMaxSliderPosition(); 33 34 // 在document上綁定mousemove事件,是為了當沒有松開鼠標,但是鼠標移出滾輪時依然能夠觸發mousemove事件,提升用戶體驗。 35 doc 36 .on('mousemove.scroll', mousemoveHandler) 37 .on('mouseup.scroll', function (e) { 38 console.log('mouseup'); 39 doc.off('.scroll'); 40 }); 41 }); 42 } 43 return self; 44 },
getMaxSliderPosition()
1 // 滑動可移動的距離 2 getMaxSliderPosition: function () { 3 var self = this; 4 return self.$bar.height() - self.$slider.height(); 5 },
mousemoveHandler()
1 function mousemoveHandler(e) { 2 e.preventDefault(); 3 console.log('mousemove'); 4 if (dragStartPagePosition == null) return; 5 self.scrollTo( 6 dragStartScrollPosition + 7 (e.pageY - dragStartPagePosition) * dragContBarRate 8 ); 9 }
scrollTo()
1 // 移動到具體位置 2 scrollTo: function (positionVal) { 3 var self = this; 4 self.$cont.scrollTop(positionVal); 5 },
_bindContScroll()
1 // 監聽內容的滾動,同步滑塊的位置 2 _bindContScroll: function () { 3 var self = this; 4 self.$cont.on('scroll', function () { 5 var sliderEl = self.$slider && self.$slider[0]; 6 if (sliderEl) { 7 sliderEl.style.top = self.getSliderPosition() + 'px'; 8 } 9 }); 10 return self; 11 },
getSliderPosition()
// 計算滑塊兒的當前位置 getSliderPosition: function () { var self = this, maxSliderPosition = self.getMaxSliderPosition(); return Math.min( maxSliderPosition, maxSliderPosition * self.$cont[0].scrollTop / self.getMaxScrollPosition() ); },
附上源碼地址:https://github.com/liuzhaoxu1996/slider-plugin
歡迎點贊,fork me 謝謝~~~