问题描述
我构建了以下函数,它会在鼠标悬停时更改跨度的内容。一切正常。唯一的问题是我不确定如何在 mouseout 时停止该功能(初始状态和 mouseout 状态应该相同)。
这是我目前的解决方案。
var squWrd = document.getElementById("squWrd");
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve,ms));
}
squWrd.onmouseover = function () {
squWrd.innerHTML = "Design.";
sleep(250).then(() => { squWrd.innerHTML = "UX."; });
sleep(500).then(() => { squWrd.innerHTML = "Marketing."; });
sleep(750).then(() => { squWrd.innerHTML = "Social Media."; });
sleep(1000).then(() => { squWrd.innerHTML = "Education."; });
sleep(1250).then(() => { squWrd.innerHTML = "Branding."; });
sleep(1500).then(() => { squWrd.innerHTML = "Packaging."; });
sleep(1750).then(() => { squWrd.innerHTML = "Design."; });
sleep(2000).then(() => { squWrd.innerHTML = "Processes."; });
sleep(2250).then(() => { squWrd.innerHTML = "E-Commerce."; });
sleep(2500).then(() => { squWrd.innerHTML = "Advertising."; });
sleep(2750).then(() => { squWrd.innerHTML = "Photos."; });
sleep(3000).then(() => { squWrd.innerHTML = "Products."; });
sleep(3250).then(() => { squWrd.innerHTML = "Logos."; });
sleep(3500).then(() => { squWrd.innerHTML = "Emotions."; });
sleep(3750).then(() => { squWrd.innerHTML = "Solutions."; });
}
squWrd.onmouseout = function () {
squWrd.innerHTML = "Solutions.";
}
大家有什么建议吗?提前致谢!
解决方法
问题在于,即使 onmouseout
被触发,仍有 sleep
承诺未决。您需要保存每个 setTimeout
调用的引用并在 onmouseout
事件中清除它。 See here。
var squWrd = document.getElementById('squWrd');
var timeoutRefs = [];
function sleep(ms) {
return new Promise(resolve => timeoutRefs.push(setTimeout(resolve,ms)));
}
squWrd.onmouseover = function () {
squWrd.innerHTML = "Design.";
sleep(250).then(() => { squWrd.innerHTML = "UX."; });
sleep(500).then(() => { squWrd.innerHTML = "Marketing."; });
sleep(750).then(() => { squWrd.innerHTML = "Social Media."; });
sleep(1000).then(() => { squWrd.innerHTML = "Education."; });
sleep(1250).then(() => { squWrd.innerHTML = "Branding."; });
sleep(1500).then(() => { squWrd.innerHTML = "Packaging."; });
sleep(1750).then(() => { squWrd.innerHTML = "Design."; });
sleep(2000).then(() => { squWrd.innerHTML = "Processes."; });
sleep(2250).then(() => { squWrd.innerHTML = "E-Commerce."; });
sleep(2500).then(() => { squWrd.innerHTML = "Advertising."; });
sleep(2750).then(() => { squWrd.innerHTML = "Photos."; });
sleep(3000).then(() => { squWrd.innerHTML = "Products."; });
sleep(3250).then(() => { squWrd.innerHTML = "Logos."; });
sleep(3500).then(() => { squWrd.innerHTML = "Emotions."; });
sleep(3750).then(() => { squWrd.innerHTML = "Solutions."; });
};
squWrd.onmouseout = function () {
timeoutRefs.forEach(function (timeoutRef) {
clearTimeout(timeoutRef)
});
timeoutRefs = [];
squWrd.innerHTML = 'Solutions.';
};
<div id="squWrd">INITIAL VALUE</div>
超时仍在运行,您需要调用 clearTimeout
。我建议您在 sleep
函数中添加第二个参数,一个传递超时引用的回调函数,这样您只能清除与文本相关的超时,而不是所有计时器。
此外,您可以将这些文本存储在数组中并对其进行迭代,而不是为每个文本调用 sleep
:
var squWrd = document.getElementById("squWrd");
function sleep(ms,cb=()=> {}) {
return new Promise(resolve => {
const time = setTimeout(() => {
resolve();
},ms);
cb(time);
});
}
const texts = ["Design","UX.","Marketing.","Social Media.","Education.","Branding.","Packaging.","Design.","Processes.","E-Commerce.","Advertising.","Photos.","Products.","Logos.","Emotions.","Solutions."];
const textTimeouts = [];
squWrd.onmouseover = function() {
texts.forEach((text,i) => {
sleep(250 * i,(time) => textTimeouts.push(time)).then(res => {
squWrd.innerHTML = text;
});
});
};
squWrd.onmouseout = function() {
squWrd.innerHTML = "Solutions.";
textTimeouts.forEach(time => clearTimeout(time));
};
<h1 id="squWrd">Solutions</h1>