效果图:
这篇文章主要讲解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) * dragContBarRate21 ??????);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 ??????doc36 ????????.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) * dragContBarRate8 ??);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 谢谢~~~
实战-jQuery实现自定义滚动条插件
原文地址:https://www.cnblogs.com/liuzhaoxu/p/8976658.html