JQuery 实现列表滚动效果
2024年12月24日大约 2 分钟
JQuery 实现列表滚动效果
效果分析
使用 JQuery 实现一个简单的滚动列表效果,就是让列表项 <li>
在其容器内自动滚动,当鼠标悬停在列表上时,滚动会暂停;鼠标移开后,滚动继续。
实现原理
滚动机制
- 利用
setInterval
函数定时调用scrollList
方法,以实现列表项的滚动。 - 通过 jQuery 的
animate
方法改变列表的margin-top
属性,从而让列表项向上移动。 - 当列表项移动到列表顶部之外时,使用 jQuery 的
insertAfter
方法将其移动到列表底部,形成循环滚动的效果。
鼠标事件处理
- 使用
mouseenter
和mouseleave
事件监听鼠标的悬停和离开操作。 - 当鼠标悬停在列表上时,清除定时器以暂停滚动,并设置容器的
overflow-y
属性为auto
,允许用户手动滚动列表。 - 当鼠标离开列表时,重新设置定时器以恢复自动滚动,并将容器的
overflow-y
属性改回hidden
,隐藏滚动条。
实现步骤
初始化
清除之前可能存在的定时器,避免重复设置。
计算相关尺寸
- 获取容器的高度
scrollHeight。
- 获取列表的总高度
ulHeight。
- 获取第一个列表项的高度和底部外边距之和
firstChildHeight。
const scrollHeight = ele.height();
const ulHeight = ele.children("ul").outerHeight();
const firstChild = ele.children("ul").children("li:first-child");
const firstChildHeight =
parseFloat(firstChild.outerHeight()) +
parseFloat(firstChild.css("margin-bottom"));
定义滚动函数
- 判断容器高度是否小于列表总高度,如果小于,就没必要滚动了。
- 使用
animate
方法改变列表的margin-top
属性,使列表项向上移动。 - 当列表项移出顶部时,使用
insertAfter
方法将该列表项移至底部,这样就可以实现循环效果。
function scrollList() {
if (parseInt(scrollHeight) < parseInt(ulHeight)) {
ele
.children("ul")
.animate({"margin-top": "-" + firstChildHeight + "px"}, function () {
$(this).css({"margin-top": "0"});
ele
.children("ul")
.children("li:first-child")
.insertAfter(ele.children("ul").children("li:last-child"));
});
}
}
设置定时器
ele.scrollInterval = setInterval(function () {
scrollList();
}, 2000);
处理鼠标事件
- 在
mouseenter
事件中清除定时器,并改变容器的overflow-y
属性为auto
。 - 在
mouseleave
事件中重新设置定时器,并将容器的overflow-y
属性改回hidden
,同时滚动到列表顶部。
ele.mouseenter(function () {
clearInterval(ele.scrollInterval);
ele.css({"overflow-y": "auto"});
});
ele.mouseleave(function () {
ele.scrollInterval = setInterval(function () {
scrollList();
}, 2000);
ele.animate({scrollTop: 0});
ele.css({"overflow-y": "hidden"});
});
最终代码
<div class="scroll-list">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
/**
* 滚动列表
* @param {HTMLElement} ele 列表元素
*/
function scrollList(ele) {
ele.scrollInterval && clearInterval(ele.scrollInterval);
const scrollHeight = ele.height();
const ulHeight = ele.children("ul").outerHeight();
const firstChild = ele.children("ul").children("li:first-child");
const firstChildHeight =
parseFloat(firstChild.outerHeight()) +
parseFloat(firstChild.css("margin-bottom"));
function scrollList() {
if (parseInt(scrollHeight) < parseInt(ulHeight)) {
ele
.children("ul")
.animate({"margin-top": "-" + firstChildHeight + "px"}, function () {
$(this).css({"margin-top": "0"});
ele
.children("ul")
.children("li:first-child")
.insertAfter(ele.children("ul").children("li:last-child"));
});
}
}
ele.scrollInterval = setInterval(function () {
scrollList();
}, 2000);
ele.mouseenter(function () {
clearInterval(ele.scrollInterval);
ele.css({"overflow-y": "auto"});
});
ele.mouseleave(function () {
ele.scrollInterval = setInterval(function () {
scrollList();
}, 2000);
ele.animate({scrollTop: 0});
ele.css({"overflow-y": "hidden"});
});
}