鼠标移开时的停止功能 | JS

问题描述

我构建了以下函数,它会在鼠标悬停时更改跨度的内容。一切正常。唯一的问题是我不确定如何在 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>

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...