听慕课学自定义滚动条

html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自定义滚动条</title>
    <link rel="stylesheet" href="./reset.css">
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <!--容器-->
    <div class="scroll_demo">
        <!--标签切换去-->
        <ul class="scroll_tab clearfix">
            <li class="tab_item tab_active">第一篇</li>
            <li class="tab_item">第二篇</li>
            <li class="tab_item">第三篇</li>
            <li class="tab_item">第四篇</li>
        </ul>
        <!--内容切换区-->
        <div class="scroll_wrap">
            <!--滚动内容-->
            <div class="scroll_cont">
                <h3 class="anchor">春天来了</h3>
                <div class="scroll_ol">
                    <p>春天来了,草长莺飞,万物复苏,到处充满勃勃生机。</p>

                    <p>春天来了,春风给新钻出地面的小草披上了绿衣。春天来了,春精灵给了桃树妹妹一个深情的吻,桃树妹妹羞红了脸儿。春天来了,柳树发芽了,那芽儿欢快地生长着,嫩嫩的、绿绿的,风微微地吹着,小芽儿随着柳枝在风中摇晃,就像一个个跳动的音符,正演奏着春天的赞歌。</p>

                    <p>春天来了,阳光明媚。冻冰了的小河在阳光照耀下懒洋洋地舒展着身子,慢悠悠地哼着小曲,舒坦极了。河里的小鱼自由自在地嬉戏着,不时嘴里还冒出几个泡泡,甭提多开心。小鸭子欢快地在水面上游动,不时呼朋引伴结队而行,甭提多快活。在这暖暖的春日里,小孩子们在田野里、小河边、草地上唱着歌儿,采着野花,享受着美好的春光。</p>

                    <p>春天来了,青蛙“呱呱”地叫着,忙着在田里捉害虫;蜜蜂“嗡嗡”地叫着,忙着在在花丛中采花酿蜜;燕子“唧唧”地叫着,忙着在屋檐下搭窝筑巢;布谷鸟“布谷,布谷”地叫着,忙着催促人们春耕播种……“沙沙沙”春雨滋润着大地,让大地焕然一新。“轰轰隆隆”春雷响彻云霄,敲响了迎春交响曲中的大鼓。</p>

                    <p>春光竟是那么的浪漫,那么的饱满。它把一冬天蕴藏的精神、力量都尽情地释放出来。</p>

                    <p>春天来了,草长莺飞,万物复苏,到处充满勃勃生机。</p>
                </div>

                <h3 class="anchor">夏天来了</h3>
                <div class="scroll_ol">
                    <p>夏天来了</p>

                    <p>温暖的春天过去了,火热夏天来了。</p>

                    <p>天气变得越来越热了,太阳火辣辣地照在大地上,好像在说:“我很厉害、万物都不是我的对手!哈哈哈!”白云也许也被太阳晒得躲了起来。只有到了傍晚,风吹在身上才会感觉有了一丝丝的凉爽。小鸟躲进了鸟窝里,狗儿躲在阴凉的方吐着舌头,大树也被晒得裂开了皮。树上的知了不住地叫:“夏天真热!知了!知了!”池塘里开满了好看的荷花,有白色的、有粉红色的,在绿色的荷叶衬托下,分处的妖娆。蜻蜓在水面上飞来飞去,有的捉害虫,有的戏嬉打闹,偶尔也会停在荷叶上休息会儿。可爱的小青蛙有的在忙着捉蚊子,还有的则坐在荷叶上呱呱叫。</p>

                    <p>夏天的游泳池可真热闹啊!人们穿着美丽的游泳衣,在游泳池里快乐的的拨着水花,击出一道道浪花,我也参加进去了,让游泳池里的水带走夏天的炎热。</p>

                    <p>夏天的水果也很丰富,有荔枝、西瓜、水蜜桃,还有火龙果。但我最喜欢吃荔枝了。听爸爸妈妈说古时候荔枝是很名贵的,一般的老百姓是吃不到的,而现在荔枝已走入千家万户了,所以夏天我总是会吃到很多很多新鲜甜美的荔枝。</p>

                    <p>夏天虽然很热,但也给我带来了很多快乐,我非常喜欢夏天!</p>
                </div>

                <h3 class="anchor">秋天来了</h3>
                <div class="scroll_ol">
                    <p>清晨,推开窗子,清风迎面而来,像极了轻纱拂过脸庞。这种凉凉的微风,许久不曾遇见过了。难道?真的,秋天就这样来了!</p>

                    <p>这种感觉,这种味道,不知在那炎热的夏天里,梦寐以求了多少次,如今,秋姑娘她终于来了,我竟然不知道,要对她如何抒发自己的思念之情!</p>

                    <p>微笑着看着湛蓝的天空,这种湛蓝也许只是属于秋天的。广阔的天空中飘着团团白云,如同这个季节里的棉絮。这时,我好像对着天空,轻轻地说:“嘿,好久不见了,我最爱的秋天。”</p>

                    <p>迫不及待的出门,笑着迎着秋风,有着丝丝凉意。对啊,这就是秋天了,秋天来了!只是这秋天,在这里却是如此的短暂,正因这样,她才显得无比珍贵。</p>

                    <p>清风吹过,泛黄的树叶随着风儿漫无边际的舞着,这是秋天里特有的舞者。好想就这样躺着,看着天空,还有偶尔飘着的那几朵白云,心情淡淡的,就如那秋风,无波无澜,好喜欢这种淡淡的感觉。让那飘零的树叶,尽情舞吧,舞累了就落在我的脸上吧!黛玉爱恋落红,扶锄葬花,我却不会埋葬这些叶子。因为,落红不是无情物,化作春泥更护花,这样它们的生命才会得到延续,它们才会成为永恒!</p>

                    <p>秋天来了,好笑的是,自己真的好激动,好想对着大街上的人们说:“嘿,你知道么,秋天来了?”</p>

                    <p>秋天来了,无声无息的!顿时整个世界也开始变得安静了。不再燥热,人也变的恬静了许多;鸟儿、雀儿也是喜欢秋姑娘的,见她来了,纷纷赞赏着她的美貌,却独独不敢喧哗,怕吵了她。</p>

                    <p>此时,田间地头的植物,庄稼是不是也披上了新的衣裳?它们是不是也在迎着柔软的秋风,谈论着自己的心事?瓜果蔬菜是不是也热闹洋洋的,准备着以百米冲刺的速度跑进市场、跑进仓库?</p>

                    <p>秋天来了,你知道了么?若你也喜欢秋天,赶紧走出房门,去感受那柔风的惬意,阳光的温柔和白云的懒散吧。或者,你也可以是坐在门前的竹椅上,泡上一壶淡淡的茶,笑看蓝天白云,落红瘦绿!</p>

                    <p>秋天来了,带来了淡淡的味道,淡淡的静谧,淡淡的诗意!这淡淡的感觉,冲淡了浮华、烦躁,它能让这颗曾经狂躁的心静下来,淡然的享受这美好的世界,五彩的生命。这淡淡的感觉,让生命在这个季节里沉淀,人生意义在这个季节里升华!人生就该这样,淡淡的就好!</p>
                </div>

                <h3 class="anchor">冬天来了</h3>
                <div class="scroll_ol">
                    <p>秋就这样静静的走了,冬天悄悄的来了。一阵寒风吹过,树叶纷纷落下,不禁打了个哆嗦。冬天的脚步近了,冬天给人坚强,冬天似乎在诉说着,对生命的一种考验,对生命的一种进取,对生命的一种享受。冬天的天空很高,冬天的风儿很冷。冬天的云彩是青色的,冬天的松树四季常青。小虫子在大树底下静静地躺着,鸟儿变得安静许多。</p>

                    <p>冬天骨子里就含蓄,不事张扬。它走过了一路的芬芳、火热与喧嚣,终于以谢幕的姿态淡定下来了。如同一位沧桑老人,流金岁月历练出来一种刚毅与深沉,坦然面对曾经的枯荣兴衰,承受着一切的喜怒哀乐,在淡定中回味童年的梦幻,反思青年的激情,盘点中年的得失。它又静若处女,把几多复杂的情感深深埋在心底,隐秘着多情与向往,按捺住所有的冲动与宣泄,在平静中期待春缘的喜乐,憧憬播种的自豪,遐思人生的美好。冬少了一些浮华,多了一份内敛;少了一些狂热,多了一份凝重,风清气正,厚积薄发。</p>

                    <p>冬天,没有夏天的炎热,却有着一种自然的冷静和坚韧。冬天,没有秋天的收获和丰盛,却有着蓄势待发的内敛和睿智。冬天,就是一幅黑白素描。线条简单,却蕴含着深奥的生命真谛。 冬天像一首优雅的古典音乐,在静静的诉说,犹如那湖面泛起的点点阳光,又似枝头挂满的音符。 在静静的流淌中,沉淀出心底那份沉静和纯洁。</p>

                    <p>冬天不需要颂扬,也不怕打击,因为冬已经从容而慷慨地呈现出了自我。万物飘零,一派肃杀,那是本性的直面;西风飕飕,雪花飘飘,那是个性的展示,任凭说长道短,众说纷纭。有人说,冬的面孔是冷峻的,岂不知那是对世间所有作秀的不屑;还有人说,冬的神态是凄美的,因为包容太多,沉淀了无尽的甘苦。所以,我想说,冬是一个极富特色的季节,一种独特的意境。真的用心去感受这种意境,也许会摄取到一种力量。</p>

                    <p>冬天来了,春天还会远吗?大家一起期待与渴望,一股热流遍全身。如果心中有希望,冬天也会变成温暖的海洋。</p>

                    <p>冬天来了,已经走过的春夏秋变成了凝固的风景画,凝聚成了刻在心海里永远的记忆和珍藏。</p>

                    <p>冬天让我明白,只有经历了与严寒奋勇拼搏,就若那迎风傲雪怒放着的梅花一样威武不屈,才会让心灵不再迷茫,让梦想不再飘渺。</p>

                    <p>走进冬天,走进寒冷,也走进希望,严寒不可怕,暴风雪也不可怕,只要我们心中拥有美好的理想,只要我们敢于拼搏,每个人都会走向成功的彼岸。</p>

                    <p>风在吹,云在走,水在流,瞬间与永恒。</p>

                    <p>冬天来了。</p>
                </div>
            </div>
            <!--滚动条-->
            <div class="scroll_bar">
                <!--滑块-->
                <div class="scroll_slider">
                    
                </div>
            </div>
        </div>
    </div>
</body>
<script  type="text/javascript" src="jquery.js"></script>
<script src="scroll.js"></script>
<script type="text/javascript">
    var scroll = new Scroll.CusScrollBar({
    contSelector   : ".scroll_cont",   // 滑动内容区选择器(必须)
       barSelector    : ".scroll_bar",    // 滑动条选择器(必须)
       sliderSelector : ".scroll_slider", // 滑动快选择器
    tabItemSelector: ".tab_item",      // 标签选择器(必须)
    tabActiveClass : "tab_active",     // 选中标签样式
    anchorSelector : ".anchor"         // 苗点选择器(必须)
   });
</script>
</html>

css

body{
    background: #ccc;
}
.scroll_demo{
    background: #fff;
    width: 540px;
    border:1px solid #e5e5e5;
    margin: 40px auto;
    box-shadow: 0px 5px 10px 2px rgba(0,0,0,0.5);
}
.scroll_tab{
    height: 34px;
    border-bottom: 1px solid #e5e5e5;
    color: #666;
    background:#f8f8f8;

}
.scroll_tab .tab_item{
    float: left;
    font: 14px/34px "Microsoft Yahei";
    height: 100%;
    text-align: center;
    padding: 0 20px;
    border-right: 1px solid #e5e5e5;
    cursor:pointer;
}
.scroll_tab .tab_active{
    color: #00be3c;
    border-top: 2px solid #00be3c;
    background:#fff;
    margin: -1px 0;
}
/* 滚动内容区 */
.scroll_wrap{
    position: relative;
    width: 100%;
    height: 300px;
}
.scroll_wrap .scroll_cont{
    height: 100%;
    overflow: hidden;
    padding: 0 15px;
}
.scroll_wrap .scroll_cont h3{
    font: 16px/3 "Microsoft Yahei";
    text-align: center;
}
.scroll_wrap .scroll_cont p{
    font-size: 14px;
    line-height: 20px;
    text-indent: 2em;
    margin-bottom: 10px; 

}
/* 滚条 */
.scroll_wrap .scroll_bar{
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 10px;
    background-color: #eaeaea;
}
.scroll_wrap .scroll_slider{
    position: absolute;
    left: 1px;
    top: 0;
    width: 8px;
    height: 30px;
    background:#333;
    cursor: pointer;
}

scroll.js

var Scroll = {};
(function(win,doc,$){
       function CusScrollBar(options) {
        // 初始化
        this._init(options);
    }
    // 在原型上添加方法
    $.extend(CusScrollBar.prototype,{
        _init : function(options) {
            var self = this;
            self.options = {
                contSelector: "",   // 滑动内容区选择器
                barSelector: "",    // 滑动条选择器
                sliderSelector: "", // 滑动块选择器
                tabItemSelector: "",// 标签选择器
                tabActiveClass: "" ,// 选中的标签样式
                anchorSelector: "", // 苗点选择器
                wheelStep: 15       // 滚动步幅
            };
            $.extend(true,self.options,options || {});
            // Dom选择函数
            self._initDomEvent();
            // 绑定滑块点击拖动事件
            self._initSliderDragEvent();
            // 绑定滚轮事件
            self._bandMouseWheel();
            // 监听内容滚动,同步滑块移动
            self._bandContScroll();
            // 点击切换标签
            self._initTabEvent();
            return self;
           },
        /*
            * 初始化DOM引用
            * @method _initDomEvent
            * @return {CusScrollBar}
            */
         _initDomEvent : function(){
            var opts = this.options;
            // 滑动内容区对象,必须填
            this.$cont = $(opts.contSelector);
            // 滑动条滑块对象,必须填
            this.$slider = $(opts.sliderSelector);
            // 滑动条对象
            this.$bar = opts.barSelector ? $(opts.barSelector) : this.$slider.parent();
         // 文档对象
            this.$doc = $(doc);
          // 标签对象
         this.$tabItem = $(opts.tabItemSelector);
         // 苗点对象
         this.$anchor = $(opts.anchorSelector);
            },
            /*
             * 初始化滑动块滑动功能
             * @return {[object]} [this]
             */
        _initSliderDragEvent: function(){
            var self = this;
            var slider = self.$slider;
            var cont = self.$cont;
            var doc = self.$doc,
                dragStartPagePosition,
                dragStartScrollPosition,
                dragContBarRate;

                function mousemoveHandler(e){
                    if(dragStartPagePosition == null){
                        return;
                    }
                    self.scrollContTo(dragStartScrollPosition + (e.pageY - dragStartPagePosition)*dragContBarRate);
                }

                slider.on("mousedown", function (event){
                    event.preventDefault();
                dragStartPagePosition = event.pageY;
                dragStartScrollPosition = cont[0].scrollTop;
                dragContBarRate = self.getMaxScrollPosition()/self.getMaxSliderPosition();

                    doc.on("mousemove.scroll", function(event){
                    event.preventDefault();
                        mousemoveHandler(event);
                }).on("mouseup.scroll", function(event){
                    event.preventDefault();
                    doc.off(".scroll");
                  });
            });
           },

           // 监听内容滚动事件,同步滑块位置
           _bandContScroll : function() {
               var self = this;
               self.$cont.on("scroll", function(e) {
                   e.preventDefault();
                   self.$slider.css( 'top', self.getSliderPosition() + 'px');
               });
           },

           // 绑定鼠标滚轮事件
           _bandMouseWheel : function() {
               var self = this;
               self.$cont.on("mousewheel DOMMouseScroll", function(e) {
                   e.preventDefault();
                   var oEv = e.originalEvent;
                   var wheelRange = oEv.wheelDelta ? -oEv.wheelDelta/120 : (oEv.detail || 0)/3;
                   self.scrollContTo(self.$cont[0].scrollTop + wheelRange * self.options.wheelStep);
               });
               return self;
           },
        /*
         *初始化标签切换功能
         * @return {[object]} [this]
         */
        _initTabEvent : function() {
            var self = this;
            self.$tabItem.on("click", function (e) {
                e.preventDefault();
                var index = $(this).index();
                self.changeTabSelect(index);
                // 切换标签后同步内容
                self.scrollContTo(self.$cont[0].scrollTop + self.getAnchorPosition(index));
            });
        },
        // 切换标签
        changeTabSelect : function (index) {
            var self = this;
            var active = self.options.tabActiveClass;
            self.$tabItem.eq(index).addClass(active).siblings().removeClass(active);
            return self;
        },

        // 获取每个苗点位置信息的数据
        getAllAnchorPosition : function () {
            var self = this;
            var allAnchor = [];
            for(var i = 0; i < self.$anchor.length; i++ ) {
                allAnchor.push(self.$cont[0].scrollTop + self.getAnchorPosition(i));
            }
            return allAnchor;
        },

        // 获取指定苗点到容器上边界的位置
        getAnchorPosition : function (index) {
            var self = this;
            return self.$anchor.eq(index).position().top;
        },

           // 获取滑块位置
           getSliderPosition : function() {
               var self = this;
               return self.$cont[0].scrollTop/(self.getMaxScrollPosition()/self.getMaxSliderPosition());
           },

        // 文档可滚动最大距离
        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();
        },

        // 滚动文档内容
        scrollContTo : function(positionVal) {
            var self = this;
            var anchorArr = self.getAllAnchorPosition();
            function getIndex(positionVal) {
                for (var i = anchorArr.length; i >= 0; i--) {
                    if (positionVal >= anchorArr[i]) return i;
                }
            }
            // 苗点数与标签数一样的话
            if(self.$tabItem.length == anchorArr.length) self.changeTabSelect(getIndex(positionVal));
                self.$cont.scrollTop(positionVal);
        }
    });
    Scroll.CusScrollBar = CusScrollBar;
})(window,document,jQuery)
原文地址:https://www.cnblogs.com/mymission/p/5802086.html