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:
- Shallow copy $. Extend (obj 1, obj 2)
- Deep copy $. Extend (true, obj 1, obj 2)
- 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>