问答详情
源自:4-1 jQuery课程总结

课讲的很好,能给一下源码码?

这介个的源码有吗,很多地方法没有太明白!!!

提问者:小访客 2016-11-19 13:06

个回答

  • newway
    2018-05-01 10:03:18

    https://github.com/liuzhaoxu1996/slider-plugin

  • 学之舟_36820
    2016-11-21 23:19:28

    第一个排版乱了,js代码可以贴后面的。

  • 学之舟_36820
    2016-11-21 23:17:24

    var Scroll = {};
    
    (function (win,doc,$) {
    	function CusScrollBar(options) {
    		if (this instanceof CusScrollBar) {
    			this.init(options);
    		} else {
    			return CusScrollBar(options);
    		}
    	}
    
    	$.extend(CusScrollBar.prototype, {
    		init: function (options) {
    			var _this = this;
    			_this.options = {
    				scrollDirection: "y",
    				contentSelector: "",
    				barSelector: "",
    				sliderSelector: "",
    				tabItemSelector: ".item",
    				tabActive: "active",
    				anchorSelector: ".anchor",
    				correctSelector: ".correct-bot",
    				articleSelector: ".article-text",
    				wheelStep: 10
    			}
    
    			$.extend(true,_this.options, options || {});
    
    			_this.initEvent();
    
    			return _this;
    		},
    		initEvent: function () {
    			var opts = this.options;
    			this.cont = $(opts.contentSelector);
    			this.slider = $(opts.sliderSelector);
    			this.bar = opts.barSelector ? $(opts.barSelector) : _this.slider.parent();
    			this.tabItem = $(opts.tabItemSelector);
    			this.anchor = $(opts.anchorSelector);
    			this.correct = $(opts.correctSelector);
    			this.article = $(opts.articleSelector);
    			this.doc = $(doc);
    
    			this.initSliderDrag().bindContentScroll().bindMouseWheel().initTabEvent().initArticleHeight();
    		},
    		initTabEvent: function () { // 监听标签事件
    			var _this = this;
    
    			this.tabItem.on("click",function (e) {
    				e.preventDefault();
    				var index = $(this).index();
    
    				_this.changeTabSelect(index); // 标签切换
    
    				_this.scrollTo(_this.cont[0].scrollTop + _this.getAnchorPosition(index)); // 内容跳转到锚点
    			})
    
    			return _this;
    		},
    		initArticleHeight: function () {
    			var _this = this,
    				lastArticle = this.article.last(),
    				lastArticleHeight = lastArticle.height(),
    				contentHeight = _this.cont.height();
    
    			if (lastArticleHeight < contentHeight) {
    				_this.correct[0].style.height = contentHeight - lastArticleHeight - _this.anchor.outerHeight() + "px";
    			}
    
    			return _this;
    		},
    		initSliderDrag: function () { // 滑块拖动功能
    			var _this = this,
    				slider = this.slider,
    			    sliderEl = slider[0];
    
    			if (sliderEl) {
    				var doc = this.doc,
    				    dragStartPagePosition,
    				    dragStartScrollPosition,
    				    dragContBarRate;
    
    				function fnMove(e) {
    					e.preventDefault();
    					if (dragStartPagePosition == null) {
    						return;
    					}
    					// 内容滑动距离 = 滑块移动距离 * 比率 + 内容开始卷曲的高度
    					// 滑块移动距离 = 鼠标释放的位置 - 鼠标开始的位置
    					var scrollRange = dragStartScrollPosition + (e.pageY - dragStartPagePosition) * dragContBarRate;
    					_this.scrollTo(scrollRange);
    				}
    
    				slider.on("mousedown",function (e) {
    					e.preventDefault();
    					dragStartPagePosition = e.pageY;
    					dragStartScrollPosition = _this.cont[0].scrollTop;
    					dragContBarRate = _this.getMaxScrollRange() / _this.getMaxSliderRange(); // 滚动比率 = 内容可滚动高度 / 滑块可移动距离
    
    					doc.on("mousemove.scroll",function (e) {
    						fnMove(e)
    					}).on("mouseup.scroll",function () {
    						doc.off("mousemove.scroll mouseup.scroll");
    					});
    				});
    
    				return _this;
    			}
    		},
    		changeTabSelect: function (index) { // 标签切换时变更自身元素和同胞元素的类名
    			var _this = this,
    				active = _this.options.tabActive;
    
    			return _this.tabItem.eq(index).addClass(active).siblings().removeClass(active);
    		},
    		getAnchorPosition: function (index) { // 指定的锚点相对于可视区位置
    			var result = this.anchor.eq(index).position().top;
    			return result;
    		},
    		getAllAnchorPosition: function () { // 获得所有锚点位置
    			var _this = this,
    				arrPosition = [];
    			// 正序开始
    			for (var i = 0; i < _this.anchor.length; i++) {
    				arrPosition.push(_this.cont[0].scrollTop + _this.getAnchorPosition(i));
    			}
    
    			return arrPosition;
    		},
    		bindContentScroll: function () { // 监听内容滚动,同步滑块位置
    			var _this = this;
    
    			_this.cont.on("scroll",function () {
    				var sliderEl = _this.slider && _this.slider[0]; // 如果两个都为object对象就返回第二个对象(第一个为jquery对象,第二个为DOM对象)
    
    				if (sliderEl) {
    					sliderEl.style.top = _this.getSliderPosition() + "px";
    				}
    			})
    
    			return _this;
    		},
    		getSliderPosition: function () { // 计算滑块当前位置
    			var _this = this,
    				maxSliderPosition = _this.getMaxSliderRange();
    
    			// 滑块移动距离 = 滑块可移动距离 * 内容滚动高度 / 内容可滚动高度
    			var result = Math.min(maxSliderPosition, maxSliderPosition * _this.cont[0].scrollTop / _this.getMaxScrollRange());
    			return result;
    		},
    		bindMouseWheel: function () { // 鼠标滚轮事件程序
    			var _this = this;
    
    			// chrome支持mousewheel 属性取值120的倍数 正值表示向上
    			// Firefox支持DOMMouseScroll 属性取值3的倍数 负值表示向上
    			_this.cont.on("mousewheel DOMMouseScroll",function (e) {
    				e.preventDefault();
    
    				// $.event.originalEvent 指向原生事件
    				var oEV = e.originalEvent,
    					wheelRange = oEV.wheelDelta ? -oEV.wheelDelta / 120 : (oEV.detail || 0) / 3;
    
    				_this.scrollTo(_this.cont[0].scrollTop + wheelRange * _this.options.wheelStep);
    			});
    
    			return _this;
    		},
    		getMaxScrollRange: function () { // 内容可滚动高度
    			var _this = this;
    			var result = Math.max(_this.cont.height(), _this.cont[0].scrollHeight) - _this.cont.height();
    			return result;
    		},
    		getMaxSliderRange: function () { // 滑块可滚动距离
    			var _this = this;
    			var result = _this.bar.height() - _this.slider.height();
    			return result;
    		},
    		scrollTo: function (positionValue) { // 内容移动程序
    			var _this = this,
    				arrPosition = this.getAllAnchorPosition();
    
    			// 滚动条位置与tab标签对应关系
    			function getIndex(positionValue) {
    				var index = 0;
    
    				// 正序开始
    				// 当scrolltop的值大于锚点定位的位置,则表示内容在那个锚点范围里面
    				for (var i = 0; i < arrPosition.length; i++) {
    					if (positionValue >= arrPosition[i]) {
    						index = i;
    					};
    				}
    
    				return index;
    			}
    
    			// 锚点数和标签数相同
    			if (arrPosition.length === _this.tabItem.length) {
    				// 标签选择事件
    				_this.changeTabSelect(getIndex(positionValue));
    			}
    
    			_this.cont.scrollTop(positionValue);
    		}
    	});
    
    	Scroll.CusScrollBar = CusScrollBar;
    })(window,document,jQuery);
    
    new Scroll.CusScrollBar({
    	contentSelector: ".content",
    	barSelector: ".scroll-bar",
    	sliderSelector: ".scroll-slider"
    });


  • 学之舟_36820
    2016-11-21 23:14:13

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>自定义滚动条</title>
    <style>
    body,ul,li,div,h3,p{margin: 0; padding: 0;}
    body{background-color: #ccc;}
    li{list-style: none;}
    
    .clx{*zoom: 1;}
    .clx:after{content: ""; display: table; clear: both;}
    
    .wrap{position: relative; width: 540px; margin: 30px auto; border: 1px solid #A489F1; background-color: #fff;}
    
    .tab{height: 34px; color: #666; background-color: #f8f8f8;}
    .tab .item{float: left; height: 32px; padding: 0 20px; font-size: 14px; line-height: 34px; text-align: center; border: 1px solid #e5e5e5;}
    .tab .active{margin: -1px 0; color: #00be3c; background-color: #fff; border-top: 2px solid #00be3c;}
    
    .main{width: 100%; height: 300px;}
    .main .content{position: relative; height: 100%; padding: 0 15px; overflow: hidden;}
    .main .content .anchor{font: 16px/3 "Microsoft Yahei"; text-align: center;}
    .main .content .article-text p{font-size: 14px; line-height: 20px; text-indent: 2rem; margin-bottom: 10px;}
    
    .scroll-bar{position: absolute; top: 0; right: 0; width: 10px; height: 100%; background-color: #eaeaea;}
    .scroll-bar .scroll-slider{position: absolute; top: 0; left: 1px; width: 8px; height: 30px; background-color: #fff;}
    </style>
    </head>
    <body>
    <div>
    <ul class="tab clx">
    <li class="item active">第一篇</li>
    <li>第二篇</li>
    <li>第三篇</li>
    <li>第四篇</li>
    </ul>
    <div>
    <div>
    <h3>绿色的春</h3>
    <div>
    <p>春的百花齐放,夏的骄阳似火,秋的硕果累累,冬的白雪皑皑,无一不成为别致的风景。勤劳、智慧而又知道享受的人们,学会了春耕夏种,秋收冬藏。知道了在春天种下希望,在夏天吹一习凉风,在秋天赏一轮月,在冬天升一炉火。</p>
    <p>当四季轮回更替时,人们的心绪便也随之折折叠叠。春恨秋悲,春愁夏伤皆因四季而起。一滴春雨,一片残荷,一夜秋风,一朵雪花都足以让心情变得敏感而丰富。人们在春中体会到了温暖,在夏中感受到了火热,在秋里寻找到了悲凉,在冬中懂得了残酷。</p>
    <p>春缠绵,夏热情,秋悲凉,冬庄严。每一个季节都象一首歌,在万物面前心情地展示它的弦律,让生灵情不自禁随之翩翩起舞。没有最好的时节,也没有最坏的时节。诚如天门慧开禅师的偈语所言:春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是人间好时节。</p>
    <p>当气温不再寒冷,当风雪不再肆虐,当春雷惊醒沉睡的大地,当种子舒展他慵懒的双臂,当枯枝抽出新芽,当燕子开始低语,当浅绿的颜色逼进眼帘,当鲜花展开迷人的笑靥……,春已翩然而至。</p>
    <p>春,轻易地便让人联想到“青春”、“光明”、“希望”这些字眼。“一年之际在于春”。人们都满怀信心地在这个季节里,开始新的一年。农民开始盘算一年的生计,商人开始预计一年的经营,文人开始酝酿新的篇章,而学子则准备着新的学业。</p>
    <p>逃离了冬的严寒,避开了夏的酷热,也没有了秋的萧瑟,春,这个季节,始终是不愠不火的,宛如一个温柔娴静的女子。偶尔的几场春雨,亦无不带来令人欣喜的清新与潮湿。于是有人说:“春雨贵如油”、“春光无限好”。为了充分领略这无限春光,在工作之余,人们常常会想到春游,去亲近大自然,让疲惫的身心在美好的春光中适意休憩。</p>
    <p>春天的时光也是短暂的。也许你还没有来得及好好感受春的气息,也许你还没有来得及实践你在春的规划,夏已“呼啸”而至。</p>
    <p>春就是这样,来无声,去无影。</p>
    </div>
    <h3>红色的夏</h3>
    <div>
    <p>夏的登场,绝不会毫无声息。</p>
    <p>夏会在清晨将阳光早早地送到千家万户,抽去人们身上懒惰的因子;夏会让蝉发出响亮的长鸣,让蛙演奏夜晚的交响曲;夏会让荷吐露沁人的芬芳,让树木尽显婀娜的身姿。</p>
    <p>灼热的阳光,倾盆的大雨,吝啬的风成了夏的招牌。</p>
    <p>夏若不是一位被娇宠的孩儿,就必定是一位热血方刚的青年。“豪爽”而“干脆”一直是夏的风格。要晴就晴它个晴空万里,要下雨就下它个酣畅淋漓。夏天的阳光,绝没有春的柔和,一缕缕都带着穿透力,似乎要把万物烤焦。夏天的雨,也绝没有春的缠绵,每一滴雨点似乎都要显示它的“份量”,一个个都掷地有声。夏天的风,轻易不来,来也是一丝丝的,有时还带着炎热的气息。</p>
    <p>夏日里的人们,有着饱满的激情和火样的热情。通常都是早早地起床,却迟迟不肯歇息。他们工作、学习都鼓足了干劲,似乎要把一年的规划放在这一季完成。夜晚,娱乐场所、夜宵摊边、公园角落也凭空地多了许多男男女女的身影。</p>
    <p>在酷热的夏季里,人们都喜欢的活动,当是游泳了。让清凉的水浸润发烫的肌肤,在水里游弋时,感觉自己成了一条自由自在的鱼。</p>
    <p>时光飞逝。或许你还在畏惧夏的炎热,或许你还在留恋水的温柔,而秋风乍起时,不觉又过了一季。</p>
    </div>
    <h3>黄色的秋</h3>
    <div>
    <p>“春种一粒粟,秋收万颗籽”。秋,是收获的季节。春天里辛勤的耕种,在秋天有了丰硕的成果。看看金黄的麦浪和累累的硕果,于是农人的眼里,便有了满意的欣喜。</p>
    <p>秋,是团圆的季节。嫦娥奔月的古老传说和中秋的习俗,使得华夏的儿女都记得在八月十五那一天,捧着圆圆的月饼,对着皎洁的月亮,尽量和家人一起团聚。</p>
    <p>秋,是思念的季节。悬挂在天空的那一轮月,最能勾起游子对故乡的思念。“床前明月光,疑是地上霜,举头望明月,低头思故乡。”李白将那种思念汇成了这首老少皆知的诗篇。</p>
    <p>秋,也是伤感的季节。秋风的呜咽,秋雨的凄迷,飘零的黄叶,飞舞的落花……,无一不牵动文人墨客敏感的心。看秋风萧瑟,听秋雨凄凄,那位有名的词人柳永说:“多情自古伤离别,更哪堪,冷落清秋节。”看台空院废,落花满地,郑如英写道:“台空院废人依旧,月沉云淡花羞。芙蓉寂寞小亭秋,黄花伤晚落,相对倍添愁”。秋,会在无意间将离愁别绪植入多愁善感的人的心里。</p>
    <p>但,大自然自有它固定的规律和节奏。你欣喜也罢,伤感也罢,秋,总以它不变的步伐,轻盈地走过。只剩下或许茫然无措的你,在独自回味。</p>
    </div>
    <h3>白色的冬</h3>
    <div>
    <p>冬日的阳光,是那样热切地被人期盼。尽管气温未必因它的出现而上升太多,但当那丝丝光芒照耀大地时,温暖的感觉便自心底升起。</p>
    <p>人们习惯在每个寒冷的日子里,渴望久违的天晴;在每一个冬季期待春暖花开。</p>
    </div>
    <div></div>
    </div>
    <div>
    <div></div>
    </div>
    </div>
    </div>
    <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript">
    var Scroll = {};
    
    (function (win,doc,$) {
    function CusScrollBar(options) {
    if (this instanceof CusScrollBar) {
    this.init(options);
    } else {
    return CusScrollBar(options);
    }
    }
    
    $.extend(CusScrollBar.prototype, {
    init: function (options) {
    var _this = this;
    _this.options = {
    scrollDirection: "y",
    contentSelector: "",
    barSelector: "",
    sliderSelector: "",
    tabItemSelector: ".item",
    tabActive: "active",
    anchorSelector: ".anchor",
    correctSelector: ".correct-bot",
    articleSelector: ".article-text",
    wheelStep: 10
    }
    
    $.extend(true,_this.options, options || {});
    
    _this.initEvent();
    
    return _this;
    },
    initEvent: function () {
    var opts = this.options;
    this.cont = $(opts.contentSelector);
    this.slider = $(opts.sliderSelector);
    this.bar = opts.barSelector ? $(opts.barSelector) : _this.slider.parent();
    this.tabItem = $(opts.tabItemSelector);
    this.anchor = $(opts.anchorSelector);
    this.correct = $(opts.correctSelector);
    this.article = $(opts.articleSelector);
    this.doc = $(doc);
    
    this.initSliderDrag().bindContentScroll().bindMouseWheel().initTabEvent().initArticleHeight();
    },
    initTabEvent: function () { // 监听标签事件
    var _this = this;
    
    this.tabItem.on("click",function (e) {
    e.preventDefault();
    var index = $(this).index();
    
    _this.changeTabSelect(index); // 标签切换
    
    _this.scrollTo(_this.cont[0].scrollTop + _this.getAnchorPosition(index)); // 内容跳转到锚点
    })
    
    return _this;
    },
    initArticleHeight: function () {
    var _this = this,
    lastArticle = this.article.last(),
    lastArticleHeight = lastArticle.height(),
    contentHeight = _this.cont.height();
    
    if (lastArticleHeight < contentHeight) {
    _this.correct[0].style.height = contentHeight - lastArticleHeight - _this.anchor.outerHeight() + "px";
    }
    
    return _this;
    },
    initSliderDrag: function () { // 滑块拖动功能
    var _this = this,
    slider = this.slider,
       sliderEl = slider[0];
    
    if (sliderEl) {
    var doc = this.doc,
       dragStartPagePosition,
       dragStartScrollPosition,
       dragContBarRate;
    
    function fnMove(e) {
    e.preventDefault();
    if (dragStartPagePosition == null) {
    return;
    }
    // 内容滑动距离 = 滑块移动距离 * 比率 + 内容开始卷曲的高度
    // 滑块移动距离 = 鼠标释放的位置 - 鼠标开始的位置
    var scrollRange = dragStartScrollPosition + (e.pageY - dragStartPagePosition) * dragContBarRate;
    _this.scrollTo(scrollRange);
    }
    
    slider.on("mousedown",function (e) {
    e.preventDefault();
    dragStartPagePosition = e.pageY;
    dragStartScrollPosition = _this.cont[0].scrollTop;
    dragContBarRate = _this.getMaxScrollRange() / _this.getMaxSliderRange(); // 滚动比率 = 内容可滚动高度 / 滑块可移动距离
    
    doc.on("mousemove.scroll",function (e) {
    fnMove(e)
    }).on("mouseup.scroll",function () {
    doc.off("mousemove.scroll mouseup.scroll");
    });
    });
    
    return _this;
    }
    },
    changeTabSelect: function (index) { // 标签切换时变更自身元素和同胞元素的类名
    var _this = this,
    active = _this.options.tabActive;
    
    return _this.tabItem.eq(index).addClass(active).siblings().removeClass(active);
    },
    getAnchorPosition: function (index) { // 指定的锚点相对于可视区位置
    var result = this.anchor.eq(index).position().top;
    return result;
    },
    getAllAnchorPosition: function () { // 获得所有锚点位置
    var _this = this,
    arrPosition = [];
    // 正序开始
    for (var i = 0; i < _this.anchor.length; i++) {
    arrPosition.push(_this.cont[0].scrollTop + _this.getAnchorPosition(i));
    }
    
    return arrPosition;
    },
    bindContentScroll: function () { // 监听内容滚动,同步滑块位置
    var _this = this;
    
    _this.cont.on("scroll",function () {
    var sliderEl = _this.slider && _this.slider[0]; // 如果两个都为object对象就返回第二个对象(第一个为jquery对象,第二个为DOM对象)
    
    if (sliderEl) {
    sliderEl.style.top = _this.getSliderPosition() + "px";
    }
    })
    
    return _this;
    },
    getSliderPosition: function () { // 计算滑块当前位置
    var _this = this,
    maxSliderPosition = _this.getMaxSliderRange();
    
    // 滑块移动距离 = 滑块可移动距离 * 内容滚动高度 / 内容可滚动高度
    var result = Math.min(maxSliderPosition, maxSliderPosition * _this.cont[0].scrollTop / _this.getMaxScrollRange());
    return result;
    },
    bindMouseWheel: function () { // 鼠标滚轮事件程序
    var _this = this;
    
    // chrome支持mousewheel 属性取值120的倍数 正值表示向上
    // Firefox支持DOMMouseScroll 属性取值3的倍数 负值表示向上
    _this.cont.on("mousewheel DOMMouseScroll",function (e) {
    e.preventDefault();
    
    // $.event.originalEvent 指向原生事件
    var oEV = e.originalEvent,
    wheelRange = oEV.wheelDelta ? -oEV.wheelDelta / 120 : (oEV.detail || 0) / 3;
    
    _this.scrollTo(_this.cont[0].scrollTop + wheelRange * _this.options.wheelStep);
    });
    
    return _this;
    },
    getMaxScrollRange: function () { // 内容可滚动高度
    var _this = this;
    var result = Math.max(_this.cont.height(), _this.cont[0].scrollHeight) - _this.cont.height();
    return result;
    },
    getMaxSliderRange: function () { // 滑块可滚动距离
    var _this = this;
    var result = _this.bar.height() - _this.slider.height();
    return result;
    },
    scrollTo: function (positionValue) { // 内容移动程序
    var _this = this,
    arrPosition = this.getAllAnchorPosition();
    
    // 滚动条位置与tab标签对应关系
    function getIndex(positionValue) {
    var index = 0;
    
    // 正序开始
    // 当scrolltop的值大于锚点定位的位置,则表示内容在那个锚点范围里面
    for (var i = 0; i < arrPosition.length; i++) {
    if (positionValue >= arrPosition[i]) {
    index = i;
    };
    }
    
    return index;
    }
    
    // 锚点数和标签数相同
    if (arrPosition.length === _this.tabItem.length) {
    // 标签选择事件
    _this.changeTabSelect(getIndex(positionValue));
    }
    
    _this.cont.scrollTop(positionValue);
    }
    });
    
    Scroll.CusScrollBar = CusScrollBar;
    })(window,document,jQuery);
    
    new Scroll.CusScrollBar({
    contentSelector: ".content",
    barSelector: ".scroll-bar",
    sliderSelector: ".scroll-slider"
    });
    </script>
    </body>
    </html>