JavaScript:如何在执行条件的特定持续时间后清除间隔

JavaScript: How to clear interval after specific duraion with condition executed

我需要运行下面的代码,并在 10 秒后停止 SetInteraval 函数,但同时要确保已执行完整的单词。

我写的代码:

var word = "I love JS More than any Programming Language in the world!";
var counter = 0;

var autoTyping = setInterval(function() {
  var h3 = document.getElementById("myh3");
  h3.innerText = word.substring(0, counter);
  counter++;

  if (counter > word.length) {
    counter = 0;

  }

}, 100);


setTimeout(function() {
  clearInterval(autoTyping);
}, 5000);

所以我需要在 5 秒后停止此代码并且发生了这种情况,但它可以停止而无需确保 "Variable word" 已完全写在 DOM 上。

好吧,你快到了。在您的 setInterval 回调中添加一行,您可以在达到字长时清除间隔。

setTimeout 回调中,首先检查元素的 innerText 值是否等于单词。这样你就可以看到完整的句子是否已经打印出来,如果是这样就停止。否则 setInterval 将继续 运行 直到达到字长。

var h3 = document.getElementById("myh3");
var word = "I love JS More than any Programming Language in the world!";
var counter = 0;

var autoTyping = setInterval(function() {
  h3.innerText = word.substring(0, counter);
  counter++;

  if (counter >= word.length) {
    clearInterval(autoTyping);
    counter = 0;
  }

}, 100);

setTimeout(function() {
  if (h3.innerText === word) {
    clearInterval(autoTyping);
  }
}, 5000);

你可以只在 if 语句中使用 clearinterval,而不需要 setTimeout 函数:

var word = "I love JS More than any Programming Language in the world!";
var counter = 0;
  var h3 = document.getElementById("myh3");
  
var autoTyping = setInterval(function() {
  h3.innerText = word.substring(0, counter);
  counter++;

  if (counter > word.length) {
    counter = 0;
    //clearInterval(autoTyping);
  }

}, 100);

setTimeout(function() {
  if(h3.innerHTML !== word) {
    h3.innerHTML = word;
  }
  clearInterval(autoTyping);
}, 10000);
<div id="myh3">

</div>

我假设您想将每个字母的 word 变量打印到 h3 元素,并在 5 秒后停止并且变量已完全键入。

这是我使用递归方法的解决方案:

[更新]

  • 添加了带超时停止器的输入循环

// word to type
var _word = "I love JS More than any Programming Language in the world!"

// target element's id
var _target = 'myh3'

// time to fully-typed the word
var _time = 5000 // ms

// speed is depend on _time and _word's length
var _speed = _time/_word.length

// your auto-typing stopper 
var _timeout = 10000 // ms

// auto-typing function
function autoType (word, target, speed, timeout) {
  var element = document.getElementById(target)
  var counter = 0
  var stopped = false
  
  function typing(){
    if(counter < word.length){
      element.innerHTML += word[counter]
      counter++
      
      setTimeout(function(){
        // recursive call
        typing()
      }, speed)
    }else{
      // check if you want it to stop
      if(stopped === false){
        // ok. you don't want it to stop now. reset counter
        counter = 0
         
        // reset the element if you want it too
        element.innerHTML = ''
        
        // start it again
        typing()
      }else{
        // console.log('auto-typing is done')
      }
    }
  }
  
  // timeout is required. you dont want a infinite loop, right?
  if(timeout){
    typing()
    
    setTimeout(function(){
      stopped = true
    }, timeout)
  }
}

// execute it
autoType(_word, _target, _speed, _timeout)
body {background: white}
<h3 id="myh3"></h3>

当涉及到区间时,我真的很喜欢使用 ES6 生成器函数。他们使代码更简洁。

这是一个可重用的 typewriter 函数示例,它接受元素、单词和间隔;并且 return 是一个 stop 函数:

function typewriter(element, word, interval){
  let stopped = false
  const iterator = (function*() {
    //This try..finally is not necessary, but ensures that typewriter stops if an error occurs
    try{
      while(!stopped){
        for(let i=0; i<word.length; i++){
          element.innerText = word.substring(0, i);
          yield
        }
      }
    }finally{
      clearTimeout(autoTyping)
    }
  })()
  const autoTyping = setInterval(() => iterator.next(), interval);
  iterator.next()

  return function stop(){
    stopped = true
  }
}

const word = "I love JS More than any Programming Language in the world!";
const h3 = document.getElementById("myh3");

const stop1 = typewriter(h3, word, 100)

setTimeout(stop1, 10000)


const secondh3 = document.getElementById("my2ndh3");
const stop2 = typewriter(secondh3, word, 100)
//Even if stopped immediately, it types the full sentence
stop2()
<h3 id="myh3"></h3>
<h3 id="my2ndh3"></h3>

为了 return 结果,你甚至可以承诺这个函数,它的优点是有一个异步错误的异常通道:

function typewriter(element, word, interval){
  let stopped = false
  const promise = new Promise((resolve, reject) => {
    const iterator = (function*() {
      try{
        while(!stopped){
          for(let i=0; i<word.length; i++){
            element.innerText = word.substring(0, i);
            yield
          }
        }
        resolve()
      }catch(e){
        reject(e)
      }finally{
        clearTimeout(autoTyping)
      }
    })()
    const autoTyping = setInterval(() => iterator.next(), interval);
    iterator.next()
  })
  promise.stop = function stop(){
    stopped = true
  }
  
  return promise
}

const word = "I love JS More than any Programming Language in the world!";
const h3 = document.getElementById("myh3");

const promise1 = typewriter(h3, word, 100)
promise1.then(() => console.log('1st example done'))
setTimeout(promise1.stop, 10000)

typewriter(null, word, 100) //Cause error with null element
  .catch(e => console.error('2nd example failed:', e.stack))
<h3 id="myh3"></h3>