js component -- custom scroll bar

Knowledge points:

Native js usually encapsulates the object in the window object prototype, and jquery can also encapsulate the object in $
  • There are three ways to call the extend method of jquery:
    1. Shallow copy $. Extend (obj 1, obj 2)
    2. Deep copy $. Extend (true, obj 1, obj 2)
    3. After adding the object $. extend({something:...}) to the jquery prototype, you can call $. Something
  • event.preventDefault() blocks the default behavior of an event
  • Event. Pagex, event. Pagey get the coordinate location of the event
  • $('...'). scrollTop() gets the height of the element beyond the top of the viewable area. $('...') [index].scrollTop(val) can set the height of the element when adding parameters
  • jquery's namespace: event.something. You can easily and quickly add and delete specified events through $(...). On ('event.something ',...), $(...). Off ('something')

js file:

(function($, win, doc) {
    function ScrollBar(opts) {
        this._init(opts);
    }

    /*********
     * $.extend
     * There are three call methods
     * 1.Shallow copy $. Extend (obj 1, obj 2) = = > obj 1 becomes a shallow copy of obj 2
     * 2.Deep copy $. Extend (true, obj 1, obj 2) = = > obj 1 deep copy obj 2
     * 3.After adding the prototype object $. extend({someobj:...}) for $, it can be called through $. Someobj
     * 
     * 
     */
    $.extend(ScrollBar.prototype, {
        /*****
         * Constructor
         * @Method _init
         * @return {self}
         */
        _init: function(opts) {
            var self = this;
            self.opts = {
                scrollDir: 'y', //Rolling direction
                contSelector: '', //Scroll content area
                barSelector: '', //scroll bar
                sliderSelector: '', //slider
                wheelStep: 15, //Roller step
                scrollItem: '', //Option button
                itemActiveClass: '', //Selected state
                anchor: '', //Anchor point
                article: '', //text
                correctSelector: '' //Correcting
            };
            $.extend(true, self.opts, opts || {}); //Deep copy

            self._initDomEvent();


            return self;
        },
        /******
         * Initialize do operation
         * @Method _initDomEvent
         * @return {ScrollBar}
         */
        _initDomEvent: function() {
            var opts = this.opts;
            this.$doc = $(doc);
            this.$cont = $(opts.contSelector);
            // console.log(this.$cont);
            // console.log(this.$cont[0]);
            this.$slider = $(opts.sliderSelector);
            this.$bar = opts.barSelector ? $(opts.barSelector) :
                self.$slider.parent();
            this.$tabItem = $(opts.scrollItem);
            this.$anchor = $(opts.anchor);
            this.$article = $(opts.article);
            this.$correct = $(opts.correctSelector);
            // console.log(this.$article)
            // console.log(this.$correct)

            this._initArticleHeight()
                ._initSliderDragEvent()
                ._initTabEvent()
                ._bindContScroll()
                ._bindMousewheel();

        },
        /***
         * Initialize slider drag function
         * @return {[object]} [this]
         * 
         */
        _initSliderDragEvent: function() {
            var self = this;
            var slider = self.$slider;

            if (slider) {
                console.log(slider)
                var doc = this.$doc,
                    dragStartPagePosition, //Where the mouse starts
                    dragStartScrollPosition, //Height above top
                    dragContBarRate; //Ratio of scroll bar to content height
                function mousemoveHandler(e) {
                    e.preventDefault();
                    if (dragStartPagePosition == null) return; //If the mouse moves, start scrolling
                    self.scrollTo((dragStartScrollPosition +
                        (e.pageY - dragStartPagePosition) * dragContBarRate));
                }
                slider.on('mousedown', function(e) {
                    e.preventDefault(); //Block default events
                    console.log('mousedown');
                    dragStartPagePosition = e.pageY; //Get the location of the event (mouse)
                    dragStartScrollPosition = self.$cont.scrollTop(); //Height above top
                    dragContBarRate = self.getMaxScrollPosition() /
                        self.getMaxSliderPosition();
                    /******
                     * event.something
                     * jqery The namespace of. something
                     * Set or remove multiple events
                     */
                    doc.on('mousemove.scroll', mousemoveHandler).
                    on('mouseup.scroll', function(e) {
                        console.log('mouseup');
                        doc.off('.scroll');
                    });
                });
            }
            return self;
        },
        //Function of initialization label
        _initTabEvent: function() {
            var self = this;
            // console.log(self.$tabItem)
            self.$tabItem.on('click', function(e) {
                e.preventDefault();
                var index = $(this).index();
                self.changeTabSelector(index);
                self.scrollTo(self.$cont[0].scrollTop +
                    self.getAnchorPosition(index));
            })
            return self;
        },

        //Initialize the article height to solve the positioning problem of the last article
        _initArticleHeight: function() {
            var self = this,
                lastArticle = self.$article.last();

            var lastArticleHeight = lastArticle.height(),
                contHeight = self.$cont.height();

            if (lastArticleHeight < contHeight) {
                self.$correct[0].style.height = contHeight -
                    lastArticleHeight - self.$anchor.outerHeight() + 'px';
            }
            return self;
        },
        //Binding content scrolling events
        _bindContScroll: function() {
            var self = this;
            self.$cont.on('scroll', function() {
                var slider = self.$slider && self.$slider[0];
                if (slider) {
                    slider.style.top = self.getSliderPosition() + 'px';
                }
            });
            return self;
        },
        //Bind wheel event
        _bindMousewheel: function() {
            var self = this;
            self.$cont.on('mousewheel DOMMousrScroll', function(e) {
                e.preventDefault();
                var oEv = e.originalEvent,
                    wheelRange = oEv.wheelDelta ? -oEv.wheelDelta / 120 : (oEv.detail || 0) / 3;
                self.scrollTo(self.$cont[0].scrollTop + wheelRange * self.opts.wheelStep)

            })
        },
        //Get the location of the target anchor
        getAnchorPosition: function(index) {
            return this.$anchor.eq(index).position().top;
        },
        //Get content scrollable height
        getMaxScrollPosition: function() {
            var self = this;
            //The overall height of the scrollHeight element,. height() visual height
            return Math.max(self.$cont[0].scrollHeight, self.$cont.height()) -
                self.$cont.height();
        },
        //Slider movable distance
        getMaxSliderPosition: function() {
            var self = this;
            return self.$bar.height() - self.$slider.height();
        },
        //Calculate the current position of the slider
        getSliderPosition: function() {
            var self = this,
                maxSliderPosition = self.getMaxSliderPosition();
            // console.log(maxSliderPosition)
            // console.log(self.$cont[0].scrollTop)
            // console.log(self.getMaxScrollPosition())
            return Math.min(maxSliderPosition,
                maxSliderPosition * self.$cont[0].scrollTop / self.getMaxScrollPosition());
        },
        //Get the location information array of each anchor
        getAllAnchorPosition: function() {
            var self = this,
                allPositionArr = [];
            for (let i = 0; i < self.$anchor.length; i++) {
                allPositionArr.push(self.$cont[0].scrollTop + self.getAnchorPosition(i));
            }
            return allPositionArr;
        },
        //Control content scrolling
        scrollTo: function(psVal) {
            var self = this;
            var posArr = self.getAllAnchorPosition();

            function getIndex(val) {
                for (let i = posArr.length - 1; i >= 0; i--) {
                    if (val >= posArr[i]) {
                        return i;
                    } else {
                        continue;
                    }
                }
            }
            //The number of anchor points is the same as the number of labels
            if (posArr.length == self.$tabItem.length) {
                self.changeTabSelector(getIndex(psVal));
            }
            self.$cont.scrollTop(psVal);
            /*****
             * scrollTop()Is a function of jq,
             * No parameters: used to get the width beyond the top
             * With parameters: set the height beyond the top
             * ****/
        },
        //Toggle label selection
        changeTabSelector: function(index) {
            var self = this,
                active = self.opts.itemActiveClass;
            return self.$tabItem.eq(index).addClass(active)
                .siblings().removeClass(active);
        },


    });
    $.extend({
        scrollBar: function(options) {
            new ScrollBar(options);
        }
    })
})(jQuery, window, document);

css code

body,
ul,
li,
h3,
p {
    margin: 0;
    padding: 0;
    font-family: 'Microsoft Yahei';
}

body {
    background-color: #ccc;
}

.scroll-demo {
    background-color: #fff;
    width: 600px;
    height: auto;
    margin: 30px auto;
}

.scroll-list {
    width: 100%;
    height: 34px;
    background-color: #bbb;
    border-bottom: 1px solid #aaa;
}

.scroll-list .scroll-item {
    float: left;
    list-style-type: none;
    height: 34px;
    line-height: 34px;
    border-right: 1px solid #aaa;
    text-align: center;
    padding: 0 20px;
    cursor: pointer;
}

.item-active {
    color: green;
    border-top: 2px solid green;
    background-color: #fff;
    margin: -1px 0;
}

.clearfix {
    clear: both;
}

.scroll-wrap {
    width: 100%;
    height: 300px;
    position: relative;
}

.scroll-wrap .scroll-content {
    position: relative;
    overflow: hidden;
    height: 300px;
    padding: 0 16px;
}

.scroll-content h3 {
    text-align: center;
    font-size: 16px/3 'Microsoft Yahei';
    height: 30px;
    line-height: 30px;
    margin: 10px 0;
}

.scroll-content .content p {
    text-indent: 2em;
    line-height: 24px;
    font-size: 14px;
    margin-bottom: 6px;
}

.scroll-bar {
    position: absolute;
    top: 0;
    right: 0;
    width: 8px;
    height: 100%;
    background-color: #bbb;
}

.scroll-bar .slide-bar {
    position: absolute;
    top: 0;
    right: 0;
    width: 8px;
    height: 30px;
    border-radius: 4px;
    background-color: rgb(195, 230, 195);
    cursor: pointer;
}

.scroll-bar .slide-bar:hover {
    background-color: rgb(42, 201, 69);
}

html code is omitted

  <script>
        /***
         * 
         * Pay attention to the incoming object, using the class selector!!!!!!!!
         * '.'It must not be lost 
         * 
         * **/
        $.scrollBar({
            scrollDir: 'y', //Rolling direction
            contSelector: '.scroll-content', //Scroll content area
            barSelector: '.scroll-bar', //scroll bar
            sliderSelector: '.slide-bar', //slider
            scrollItem: '.scroll-item', //Label item
            itemActiveClass: 'item-active', //Tag selection status Class
            anchor: '.anchor',
            article: '.content', //text
            correctSelector: '.content-bottom' //Corrected height
        });
    </script>

Keywords: JQuery

Added by AngelicS on Tue, 05 May 2020 12:05:43 +0300