123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- /*
- 用途项目:自定义滚动条实现
- */
-
- (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: 10, //滚动步长(鼠标移动一下,内容滚动的幅度)
- }
- // 覆盖参数
- $.extend(true, self.options, options||{});
- self._initDomEvent();
- $(window).on("resize",function(){
- 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.$scrollDir = opts.scrollDir || "Y"
- // 获取文档对象
- this.$doc = $(doc);
- // 获取初始化滑块拖动功能
- this._initSliderDragEvent();
- // 获取同步滑块的位置
- this._bindContentScroll();
- // 获取鼠标滚轮事件
- this._bindMousewheel();
- // 获取内容来定义滑块的高度
- this._initSliderHeight();
- },
- // 根据内容来定义滑块的高度
- _initSliderHeight: function() {
- var rate;
- var sliderHeight;
- if(this.$scrollDir == "Y"){
- rate = this.$cont.height() /this.$cont[0].scrollHeight;
- if(!this.$bar.css("top")){
- this.$bar.css({
- "top": "0px"
- })
- }
-
- sliderHeight = rate*this.$bar.height();
- this.$slider.css('height',sliderHeight);
- }else{
- rate = this.$cont.width() /this.$cont[0].scrollWidth;
- this.$bar.css({
- "width": "100%",
- "height": "5px",
- "bottom": "0px",
- "zIndex": "100",
- })
- this.$slider.css({
- "height":"5px"
- })
- sliderHeight = rate*this.$bar.width();
- this.$slider.css('width',sliderHeight);
- }
-
- if(rate === 1){
- this.$bar.css('display','none');
- }
- // 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*(鼠标释放的位置-开始的位置) == 就是内容滑动的位置
- if(self.$scrollDir == "Y"){
- self.scrollTo(dragStartScrollPostion + (e.pageY - dragStartPagePostion)*dragContBarRate);
- }else{
- self.scrollTo(dragStartScrollPostion + (e.pageX - dragStartPagePostion)*dragContBarRate);
- }
-
- }
- slider.on('mousedown', function(e){
- e.preventDefault();
- e.stopPropagation()
- if(self.$scrollDir == "Y"){
- // 获取鼠标的点击的开始位置
- dragStartPagePostion = e.pageY;
- // 获取内容区域的向上卷区的高度
- dragStartScrollPostion = self.$cont[0].scrollTop;
- dragContBarRate = self.getMaxScrollPosition()/self.getMaxSliderPosition();
- }else{
- // 获取鼠标的点击的开始位置
- dragStartPagePostion = e.pageX;
- // 获取内容区域的向上卷区的高度
- dragStartScrollPostion = self.$cont[0].scrollLeft;
- dragContBarRate = self.getMaxScrollPosition()/self.getMaxSliderPosition();
- }
-
- // 监听的document对象
- doc.on('mousemove.scroll', mousemoveHandler).on('mouseup.scroll',function(){
- doc.off('.scroll');
- });
- self.$cont.on("mouseleave",function(e){
- e.stopPropagation()
- doc.off('.scroll');
- })
- });
- slider.on("click",function(e){
- e.stopPropagation()
- })
- this.$bar.on("click",function(e){
- var scrollHei
- dragContBarRate = self.getMaxScrollPosition()/self.getMaxSliderPosition();
- if(self.$scrollDir == "Y"){
- if(e.offsetY > slider.height()){
- self.scrollTo((e.offsetY - slider.height())*dragContBarRate);
- }else{
- self.scrollTo(e.offsetY*dragContBarRate);
- }
-
- }else{
- if(e.offsetX > slider.width()){
- self.scrollTo((e.offsetX - slider.width())*dragContBarRate);
- }else{
- self.scrollTo(e.offsetX*dragContBarRate);
- }
- }
- // dragStartScrollPostion = self.$cont[0].scrollTop;
- })
-
- return self;
- }
- },
-
- // 计算滑块的当前位置
- getSliderPosition: function() {
- var self = this,
- // 滑块可以移动的距离
- maxSliderPosition = self.getMaxSliderPosition();
- // 滑块移动的距离
- var sliderPosition;
- if(self.$scrollDir == "Y"){
- sliderPosition = Math.min(maxSliderPosition, maxSliderPosition*self.$cont[0].scrollTop/self.getMaxScrollPosition());
- }else{
- sliderPosition = Math.min(maxSliderPosition, maxSliderPosition*self.$cont[0].scrollLeft/self.getMaxScrollPosition());
- }
- return sliderPosition;
- },
- // 内容可滚动的高度
- getMaxScrollPosition: function() {
- var self = this;
- var maxScrollPosition;
- if(self.$scrollDir == "Y"){
- maxScrollPosition = Math.max(self.$cont.height(), self.$cont[0].scrollHeight) - self.$cont.height();
- }else{
- maxScrollPosition = Math.max(self.$cont.width(), self.$cont[0].scrollWidth) - self.$cont.width();
- }
- return maxScrollPosition
-
- },
- //滑块可移动的距离
- getMaxSliderPosition: function(){
- var self = this;
- const paddingTop = parseInt(self.$cont.css("paddingTop"))
- const paddingBottom = parseInt(self.$cont.css("paddingBottom"))
- const paddingLeft = parseInt(self.$cont.css("paddingLeft"))
- const paddingRight = parseInt(self.$cont.css("paddingRight"))
- if(self.$scrollDir == "Y"){
- return self.$bar.height()+paddingTop*3+paddingBottom*3 + - self.$slider.height();
- }else{
- return self.$bar.width()+paddingLeft*3+paddingRight*3 + - self.$slider.width();
- }
-
- },
- // 监听内容的滚动,同步滑块的位置
- _bindContentScroll: function() {
- var self = this;
- self.$cont.on('scroll', function(){
- var sliderEl = self.$slider && self.$slider[0];
- if (sliderEl) {
- // 设置滑块的位置
- if(self.$scrollDir == "Y"){
- sliderEl.style.top = self.getSliderPosition() + 'px';
- }else{
- sliderEl.style.left = 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方法。
- if(self.$scrollDir =="Y"){
- self.scrollTo(self.$cont[0].scrollTop + wheelRange*self.options.wheelStep)
- }
-
- if(self.$cont[0].scrollTop !==0 ){
- e.stopPropagation()
- }
-
- });
- },
- // 内容的滑动
- scrollTo: function(positonVal) {
- var self = this;
- if(self.$scrollDir =="Y"){
- self.$cont.scrollTop(positonVal);
- }else{
- self.$cont.scrollLeft(positonVal);
- }
-
- }
- });
- win.CusScrollBar = CusScrollBar;
- })(window,document,jQuery)
|