自定义滚动条组件封装

HTML部分

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <link rel="stylesheet" type="text/css" href="css/reset.css"/>
        <link rel="stylesheet" type="text/css" href="css/index.css"/>
    </head>
    <body>
        <!--自定义滚动条最外层容器-->
        <div class="slider-con">
            <!--tab容器-->
            <ul class="tab-con">
                <li class="tab-item active">春天的故事</li>
                <li class="tab-item">夏天的故事</li>
                <li class="tab-item">秋天的故事</li>
                <li class="tab-item">冬天的故事</li>
            </ul>
            <!--滚动条内容区-->
            <div class="slider-text-con">
                <div class="slider-text">
                    <!--春天的故事-->
                    <div class="spring-story story">
                        <h3 class="title">春天的故事</h3>
                        <p class="context">
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                        </p>
                    </div>
                    
                    <!--夏天的故事-->
                    <div class="summy-story story">
                        <h3 class="title">夏天的故事</h3>
                        <p class="context">
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                        </p>
                    </div>
                    
                    <!--秋天的故事-->
                    <div class="qiut-story story">
                        <h3 class="title">秋天的故事</h3>
                        <p class="context">
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                        </p>
                    </div>
                    
                    <!--冬天的故事-->
                    <div class="win-story story">
                        <h3 class="title">冬天的故事</h3>
                        <p class="context">
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                            地方海事局和地方了萨芬的拉萨
                            发货的老师发来的沙发里打开撒
                            分行贷款来撒会反馈到拉萨发了
                            多少开发大咖浪费好多啦大萨达
                            范德萨范德萨发生发生法萨芬的
                            范德萨范德萨发撒范德萨发生法
                            废物废物个人感情啊服务器发送
                        </p>
                    </div>
                </div>
                <!--滚动条槽-->
                <div class="slider-bar">
                    <!--滚动条滑块-->
                    <div class="slider"></div>
                </div>
            </div>
        </div>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
        <script src="js/index.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
        
        
        </script>
    </body>
</html>

-------------------------------------------------------------------------------------------------end

JS逻辑部分


//(function(win,doc,$){
    $(function(){
        
        //定义滑块类
        function slider( options ){
            this._init( options )
        };
        $.extend(slider.prototype, {
            _init:function( options ){
                //设置初始配置参数
                this.options = {
                    //滚动的方向 y  x 
                    origin:"y",
                    //滚动条
                    sliderBarEle:'',
                    //滚动内容区
                    sliderContEle:'',
                    //滚动滑块
                    sliderEle:'',
                    //鼠标滑轮滚动一格定义的距离
                    wheelStep:20,
                    
                };
                //如果有传参就合并
                this.options = options?$.extend(true,this.options,options):this.options
        
                
                //定义各事件
                this._bindEvent();
                
            },
            /*
             * 获取个节点
             */
            _fgetElement:function(){
                //tab item
                this.$tabItem = $(".tab-item");
                
                //滚动内容区
                this.$sliderText = $(".slider-text");
                
                //每篇故事
                this.$story = $(".story");
                
                //滚动条
                this.$sliderBar = $(".slider-bar");
                
                //滑块
                this.$slider = $(".slider");
                this.$doc = $(document);
            },
            /*
             * 绑定各事件
             */
            _bindEvent:function(){
                //获取元素
                this._fgetElement();
                //获取初始化数据
                this._fgetData();
                //鼠标事件--
                this._fmouseEvent();
                
                //点击切换tab
                this._fchangeTab();
                //鼠标滚轮事件
                this._fmouseWheelEvent();
            },
            /*
             * 获取各元素高度等数据
             */
            _fgetData:function(){
                //获取内容区可见高度
                this.textCanSeeHight = this.$sliderText.height();
                //获取内容完整高度
                this.textAllHeight = this.$sliderText[0].scrollHeight;
                //获取滚动条高度
                this.sliderBarHight = this.$sliderBar.height();
                //获取滑块高度
                this.sliderHeight = this.$slider.height();
                //滑块可移动距离
                this.sliderCanMoveHeight = this.sliderBarHight - this.sliderHeight;
                
                //内容可移动距离
                this.textCanMoveHeight = Math.max(this.textAllHeight,this.textCanSeeHight) - this.textCanSeeHight;//防止出现负数情况
                
                //获取比率
                this.rate =this.textCanMoveHeight/this.sliderCanMoveHeight;//内容可移动的距离除以滑块可移动的距离
                
                this.textPlaceArr = this._fgetTextPlace();
            },
            /*
             * 定义鼠标事件
             */
            _fmouseEvent:function(){
//                var _this = this;
//                var isDown = true;
//                //绑定鼠标点下事件
//                this.$doc.on("mousedown",function(e){
//                    e.preventDefault();
//                    var startY = e.pageY;
//                    if( isDown ){
//                        $(this).on("mousemove",function(e){
//                            var endY = e.pageY;
//                            var ranges = endY - startY;
//                            
//                            var canUseRange = _this._filter( ranges );
//                            
//                            
//                            _this.$slider[0].style.top = canUseRange + "px";
//                            
//                            _this._fscrollTo( canUseRange/_this.rate );    
//                            var ids =  _this._fselectTab( canUseRange/_this.rate );
//                            _this.$tabItem.eq(ids).addClass("active").siblings().removeClass("active");                                
//                                
//                    });
//                    }else{
//                        $(this).off("mousemove")
//                    }
//                    
//                    $(this).on("mouseout",function(e){
//                        isDown = false;                        
//                    })
//                })


                var slider = this.$slider,
                    _this = this,
                    sliderDom = slider[0];//注意  只有dom节点元素才能用if来判断是否存在  jq对象不行
                    if( sliderDom ){
                        //定义初始化位置数据
                        var doc = this.$doc,
                            startY,//光标相对于文档的初始Y值
                            contentScrollTop;//获取内容容器相对于边界超出的初始距离                                                       
                            
                            function mouseMove(e){//定义滑块移动时逻辑处理
                                e.preventDefault();
                                var ranges = e.pageY - startY;
                                if( contentInitScrollTop == null ){//容错处理
                                    return;
                                }
                                _this.$slider[0].style.top = _this._filter( ranges ) + "px";
                                _this._fscrollTo( contentInitScrollTop + ranges*_this.rate )//初始距离加上移动后的距离
                            };
                            
                            //滑块按下鼠标事件
                            slider.on("mousedown",function( e ){
                                e.preventDefault();
                                startY = e.pageY;//记录鼠标初始位置
                                contentInitScrollTop = _this.$sliderText[0].scrollTop;//记录内容初始溢出距离
                                //添加鼠标移动事件、将其挂载在doc上 以便当鼠标移出滑块后还能继续拖动
                                doc.on("mousemove.sliderMove",mouseMove).on("mouseup",function(){
                                    $(this).off(".sliderMove")
                                })
                            })
                    }
            },
            /*
             * 鼠标滚轮事件
             */
            
            _fmouseWheelEvent:function(){
                var _this = this;
                _this.$sliderText.on("mousewheel DoMMouseScroll",function(e){
                    e.preventDefault();
                    var oEv = e.originalEvent,
                    //获取鼠标滚轮的滚动次数     火狐浏览器是detail  正数表示向上 且值为3的倍数    其他浏览器为wheelDelta  负数为向上   且为120的倍数
                    whellRange = oEv.wheelDelta ? - oEv.wheelDelta/120 :(oEv.detail || 0)/3,
                    //内容滚动的距离
                    conTextRange =  _this.$sliderText[0].scrollTop +_this.options.wheelStep*whellRange;
                    //同步滑块的距离
                    _this.$slider[0].style.top = _this._filter( conTextRange/_this.rate ) + "px";
                    _this._fscrollTo(conTextRange)//累计叠加
                })
            },
            /*
             * tab切换逻辑
             */
            _fchangeTab:function(){
                var _this = this;
                this.$tabItem.on("click",function(){
                    //记录点击的item下标
                    _this.selectId = $(this).index();
                    //给选中的tab添加选中样式
                    $(this).addClass("active").siblings().removeClass("active");
                    _this._fscrollTo( _this.textPlaceArr[_this.selectId] ) 
                })
            },
            /*
             * _fselectTab  拖动后高亮对应的tab item
             */
            _fselectTab:function( range ){            
                for( var i = this.textPlaceArr.length-1;i >=0; i-- ){
                    if ( range>=this.textPlaceArr[i] ){
                
                        return i;
                    }
                }
                
            },
            /*
             * 获取文章节点的top值 并保存在数组中
             */
            _fgetTextPlace:function(){
                var arr = [];
                for( var i = 0;i < this.$story.length; i++ ){
                    arr.push(this.$story.eq(i).position().top)
                }
                return arr
            },
            /*
             * 改变文章容器的scrollTop值  
             */
            _fscrollTo:function( param ){
                this.$sliderText.scrollTop( param )//设置内容容器溢出上边界距离
            },
            /*
             * 限制滑块滑动的距离在合法范围内  
             */
            _filter:function( range ){
                
                if( range<0  ){
                    range = 0;
                }else if( range>this.sliderCanMoveHeight ){
                    range = this.sliderCanMoveHeight
                }
                return range;
            }
        });
        new slider({
            
                    //滚动内容区
            sliderContEle:'haha'
        
        });
    })

//(window,document,jQuery))
 

猜你喜欢

转载自blog.csdn.net/weixin_41421227/article/details/87609395