/* 用途项目:自定义滚动条实现 */ (function(win, doc, $){ // 定义的滚动条的构造函数 function CusScrollBar(options) { // 函数的调用 this._init(options); } // 对象的合并 $.extend(CusScrollBar.prototype, { _init: function(options){ // 闭包 var self = this; // 初始化参数 self.options = { scrollDir: 'Y', //滚动的方向 contentSelector: '', //滚动内容区选择器 barSelector: '', //滚动条选择器 sliderSelector: '', //滚动滑块选择器 wheelStep: 100, //滚动步长(鼠标移动一下,内容滚动的幅度) } // 覆盖参数 $.extend(true, self.options, options||{}); self._initDomEvent(); return self; }, /** * 初始化DOM引用 * @method _initDomEvent * @return {CusScrollBar} */ _initDomEvent: function() { var opts = this.options; // 滚动内容区对象,必填项 this.$cont = $(opts.contentSelector); // 滚动条滑块对象,必须项 this.$slider = $(opts.sliderSelector); // 滚动条对象 this.$bar = opts.barSelector ? $(opts.barSelector) : self.$slider.parent(); // 获取文档对象 this.$doc = $(doc); // 获取初始化滑块拖动功能 this._initSliderDragEvent(); // 获取同步滑块的位置 this._bindContentScroll(); // 获取鼠标滚轮事件 this._bindMousewheel(); // 获取内容来定义滑块的高度 this._initSliderHeight(); }, // 根据内容来定义滑块的高度 _initSliderHeight: function() { var rate = this.$cont.height()/this.$cont[0].scrollHeight; var sliderHeight = rate*this.$bar.height(); this.$slider.css('height',sliderHeight); }, /** * 初始化滑块拖动功能 * @return {[Object]} [this] */ _initSliderDragEvent: function() { var self = this; // 滑块元素 var slider = this.$slider, sliderEl = slider[0]; // 如果元素存在 if (sliderEl) { var doc = this.$doc, dragStartPagePostion, dragStartScrollPostion, dragContBarRate; function mousemoveHandler(e) { e.preventDefault(); if (dragStartPagePostion == null) { return; } //内容开始卷曲的高度+rate*(鼠标释放的位置-开始的位置) == 就是内容滑动的位置 self.scrollTo(dragStartScrollPostion + (e.pageY - dragStartPagePostion)*dragContBarRate); } slider.on('mousedown', function(e){ e.preventDefault(); // 获取鼠标的点击的开始位置 dragStartPagePostion = e.pageY; // 获取内容区域的向上卷区的高度 dragStartScrollPostion = self.$cont[0].scrollTop; dragContBarRate = self.getMaxScrollPosition()/self.getMaxSliderPosition(); // 监听的document对象 doc.on('mousemove.scroll', mousemoveHandler).on('mouseup.scroll',function(){ doc.off('.scroll'); }); }); return self; } }, // 计算滑块的当前位置 getSliderPosition: function() { var self = this, // 滑块可以移动的距离 maxSliderPosition = self.getMaxSliderPosition(); // 滑块移动的距离 return Math.min(maxSliderPosition, maxSliderPosition*self.$cont[0].scrollTop/self.getMaxScrollPosition()); }, // 内容可滚动的高度 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(); }, // 监听内容的滚动,同步滑块的位置 _bindContentScroll: function() { var self = this; self.$cont.on('scroll', function(){ var sliderEl = self.$slider && self.$slider[0]; if (sliderEl) { // 设置滑块的位置 sliderEl.style.top = self.getSliderPosition() + 'px'; } }); return self; }, // 鼠标滚轮事件 _bindMousewheel: function() { var self = this; // on监听事件,多个事件利用空格分开 self.$cont.on('mousewheel DOMMouseScroll',function(e){ e.preventDefault(); // 判断原生事件对象的属性 var oEv = e.originalEvent, //原生事件对象,(其他浏览器负数向下,firefox正数向下,所以在wheelDelta前面有负数) // 想要达到的效果,鼠标向下滚动,内容向下走 wheelRange = oEv.wheelDelta ? -oEv.wheelDelta/120 : (oEv.detail || 0)/3; // 调用scrollTo方法。 self.scrollTo(self.$cont[0].scrollTop + wheelRange*self.options.wheelStep) }); }, // 内容的滑动 scrollTo: function(positonVal) { var self = this; self.$cont.scrollTop(positonVal); } }); win.CusScrollBar = CusScrollBar; })(window,document,jQuery)