如何在单击时停止执行函数

问题描述

我有这种打字机效果,我也有一个 3 种语言的网站。更改语言时,我希望使用新语言重新执行脚本。为此,我添加一个 onclick 事件。一切正常,但有一个错误,如果我们在脚本执行过程中更改语言,新的将在旧的之上执行。那么,在我的情况下,如何停止旧脚本并执行新脚本?

我尝试使用其他答案中发布的 return,尝试使用 clearTimeout 但仍然无效。

代码段不起作用。我正在使用 localStorage,在这里它看起来像是被锁定了。

更新。该代码段已在运行。

var isTag,text,langText,i = 0;
  langText = "Hi!<br>Text,<br>Text ";
(function e() {
  if ((text = langText.slice(0,++i)) !== langText) {
    document.querySelector(".index-title-main h1").innerHTML = text;
    var t = text.slice(-1);
    if ("<" === t && (isTag = !0),">" === t && (isTag = !1),isTag) return e();
    setTimeout(e,100);
  }
}());
document.querySelector('.en').onclick = function() {
  var isTag,i = 0;
    langText = "Hi!<br>Text,<br>Text ";
  (function e() {
    if ((text = langText.slice(0,++i)) !== langText) {
      document.querySelector(".index-title-main h1").innerHTML = text;
      var t = text.slice(-1);
      if ("<" === t && (isTag = !0),isTag) return e();
      setTimeout(e,100);
    }
  }());
};
document.querySelector('.de').onclick = function() {
  var isTag,i = 0;
    langText = "Hallo!<br>Text,100);
    }
  }());
};
document.querySelector('.ru').onclick = function() {
  var isTag,i = 0;
    langText = "Привет!<br>Текст,<br>Текст ";
  (function e() {
    if ((text = langText.slice(0,100);
    }
  }());
};
.lang{
  display: flex;
}
.lang a{
  color: #000;
  width: 100px;
  display: block;
  transition: .5s;
  font-weight: bold;
  text-align: center;
  text-decoration: none;
  border: 1px solid #000;
}
.lang a:not(:last-child){
  margin-right: 10px;
}
.lang a:hover{
  color: #fff;
  transition: .5s;
  background-color: #000;
}
.index-title-main{
  padding-left: 50px;
}
<div class="lang">
  <a class="en" href="#">English</a>
  <a class="de" href="#">Deutsche</a>
  <a class="ru" href="#">Русский</a>
</div>
<div class="index-title-main">
  <h1></h1>
</div>

解决方法

我重构了您的代码并将常用函数移到了点击事件处理程序之外。

我们需要在函数开始时清除间隔,因为我们可以确定,当执行到达这里时,我们不再需要其他语言点击处理程序的任何先前运行实例。

var langText,i = 0,timeout;

langText = "Hi!<br>Text,<br>Text ";

function animateText() {
  var isTag,text;
  timeout && clearTimeout(timeout);
  if ((text = langText.slice(0,++i)) !== langText) {
    document.querySelector(".index-title-main h1").innerHTML = text;
    var t = text.slice(-1);
    if ("<" === t && (isTag = !0),">" === t && (isTag = !1),isTag) return animateText();
    timeout = setTimeout(animateText,100);
  }
};

animateText();

document.querySelector('.en').onclick = function() {
  i = 0,langText = "Hi!<br>Text,<br>Text ";
  animateText();
};

document.querySelector('.de').onclick = function() {
  i = 0,langText = "Hallo!<br>Text,<br>Text ";
  animateText();
};

document.querySelector('.ru').onclick = function() {
  i = 0,langText = "Привет!<br>Текст,<br>Текст ";
  animateText();
};
.lang{
  display: flex;
}
.lang a{
  color: #000;
  width: 100px;
  display: block;
  transition: .5s;
  font-weight: bold;
  text-align: center;
  text-decoration: none;
  border: 1px solid #000;
}
.lang a:not(:last-child){
  margin-right: 10px;
}
.lang a:hover{
  color: #fff;
  transition: .5s;
  background-color: #000;
}
.index-title-main{
  padding-left: 50px;
}
<div class="lang">
  <a class="en" href="#">English</a>
  <a class="de" href="#">Deutsche</a>
  <a class="ru" href="#">Русский</a>
</div>
<div class="index-title-main">
  <h1></h1>
</div>

,

这是一个 DRY 版本

const langTexts = {
  en: "Hi!<br>Text,<br>Text ",de: "Hallo!<br>Text,ru: "Привет!<br>Текст,<br>Текст "
}
let langText = langTexts["en"]; // langText[languageFromLocalStorage || "en"]  
let tId,isTag,cnt = 0;
const h1 = document.querySelector(".index-title-main h1");
const typer = () => {
  if ((text = langText.slice(0,++cnt)) !== langText) {
    h1.innerHTML = text;
    const t = text.slice(-1);
    if ("<" === t && (isTag = !0),isTag) return typer();
    tId = setTimeout(typer,100);
  }
}

document.getElementById("nav").addEventListener("click",e => {
  e.preventDefault();
  const tgt = e.target;
  console.log(tgt.getAttribute("lang"))
  cnt = 0;
  langText = langTexts[tgt.getAttribute("lang")];
  clearTimeout(tId)
  tId = setTimeout(typer,100);
})
typer()
.lang {
  display: flex;
}

.lang a {
  color: #000;
  width: 100px;
  display: block;
  transition: .5s;
  font-weight: bold;
  text-align: center;
  text-decoration: none;
  border: 1px solid #000;
}

.lang a:not(:last-child) {
  margin-right: 10px;
}

.lang a:hover {
  color: #fff;
  transition: .5s;
  background-color: #000;
}

.index-title-main {
  padding-left: 50px;
}
<div id="nav">
  <a class="langLink" href="#" lang="en">English</a>
  <a class="langLink" href="#" lang="de">Deutsch</a>
  <a class="langLink" href="#" lang="ru">Русский</a>
</div>
<div class="index-title-main">
  <h1></h1>
</div>