/* 用途项目:自定义滚动条实现 */ (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)