为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

正在回答

4 回答

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

0 回复 有任何疑惑可以回复我~

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

1 回复 有任何疑惑可以回复我~
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"
});


1 回复 有任何疑惑可以回复我~
#1

小访客 提问者

非常感谢!!!!
2016-12-30 回复 有任何疑惑可以回复我~
<!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>


3 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
jQuery实现自定义滚动条
  • 参与学习       39577    人
  • 解答问题       76    个

来一次jQuery封装之旅,本教程带你深入理解滚轮事件交互

进入课程

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

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信