如何在3秒后停止包含setInterval的JavaScript Marquee滚动?
内容滚动停止的正确解决方法
你当前的停止方式无效,原因是window.removeEventListener只能移除未触发的事件监听,但页面加载完成后Marquee已经执行,里面的setInterval一直在后台运行,而且你没保存它的定时器ID,根本没法终止它。
核心解决思路
setInterval启动时会返回一个唯一的定时器ID,必须用clearInterval(定时器ID)才能停止它的循环运行。
修改后的代码示例
// 定义全局变量保存定时器ID,方便后续访问 let marqueeTimer; function Marquee(selector, speed) { const parentSelector = document.querySelector(selector); const clone = parentSelector.innerHTML; const firstElement = parentSelector.children[0]; let i = 0; parentSelector.insertAdjacentHTML('beforeend', clone); parentSelector.insertAdjacentHTML('beforeend', clone); // 把setInterval的返回值存到全局变量里 marqueeTimer = setInterval(function () { firstElement.style.marginLeft = `-${i}px`; if (i > firstElement.clientWidth) { i = 0; } i = i + speed; }, 0); } // 页面加载完成后启动滚动 window.addEventListener('load', () => Marquee('.pot', 1)); // 3秒后停止滚动 setTimeout(function() { clearInterval(marqueeTimer); }, 3000);
为什么原来的方法没用?
window.removeEventListener('load', Marquee...)完全无效,因为load事件已经触发过了,这个监听早就执行完毕,移除它对已经运行的定时器没有任何影响。- 只有通过
clearInterval传入对应的定时器ID,才能真正终止setInterval的循环执行。
可选的模块化写法(避免全局变量)
如果不想用全局变量,可以让Marquee函数返回定时器ID,这样代码更干净:
function Marquee(selector, speed) { const parentSelector = document.querySelector(selector); const clone = parentSelector.innerHTML; const firstElement = parentSelector.children[0]; let i = 0; parentSelector.insertAdjacentHTML('beforeend', clone); parentSelector.insertAdjacentHTML('beforeend', clone); // 直接返回定时器ID return setInterval(function () { firstElement.style.marginLeft = `-${i}px`; if (i > firstElement.clientWidth) { i = 0; } i = i + speed; }, 0); } let marqueeTimer; window.addEventListener('load', () => { // 启动时保存ID marqueeTimer = Marquee('.pot', 1); }); // 3秒后停止 setTimeout(function() { clearInterval(marqueeTimer); }, 3000);
内容的提问来源于stack exchange,提问作者user198989
相关产品推荐
相关产品推荐

