【问题标题】:JavaScript: How to clear interval after specific duraion with condition executedJavaScript:如何在执行条件的特定持续时间后清除间隔
【发布时间】:2020-04-11 10:35:23
【问题描述】:

我需要运行以下代码,并在 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 秒后停止此代码并且这发生了,但它可以在不确保在 DOM 上完全写入完整单词“变量字”的情况下停止。

【问题讨论】:

  • 变量词是什么意思?
  • @SaoudElTelawy 所以你希望这个函数每秒运行一次,直到你的句子完全显示在屏幕上?
  • 完全是@ElmanHuseynov,但我想选择在 10 秒后停止此功能但完整句子出现的时间,因为我尝试过但没有希望!
  • @SaoudElTelawy 那么也许您需要设置句子的每个字母出现在屏幕上的时间?例如,如果单词有 10 个字母,则使它们每秒 1 个字母,将在 10 秒内得到结果。
  • @ElmanHuseynov 更多澄清......你的意思是什么?

标签: javascript html settimeout setinterval


【解决方案1】:

我假设您希望将 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}
&lt;h3 id="myh3"&gt;&lt;/h3&gt;

【讨论】:

  • @Faris Han 感谢您提供如此惊人的解释.. 但是如果我需要第一次打印这个词然后计数器为零并一次又一次地打印...稍后,在 10秒停止打印但不幸的是打印的单词缺少一些字母..如何克服?
  • @SaoudElTelawy 好的,我明白了。查看我编辑的答案。是这个意思吗?
【解决方案2】:

嗯,你快到了。在您的 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);

【讨论】:

  • 感谢您的回答.. 这很好,但我需要此功能继续运行,就像打印出完整的句子然后计数器 = 零并再次打印出来,完成 10 秒,然后被 ( SettimeOut) 但是代码要考虑一次以停止整个句子的编写!!
【解决方案3】:

你可以只在你的 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>

【讨论】:

  • 非常感谢,伙计们,但我需要@Ma'moun,这个函数会一直运行,比如整个句子要打印 3 次,然后在 10 秒后停止,但要考虑整个句子被打印出来。
  • 不确定我是否收到您的评论,我这里的示例一直运行到打印出整个句子,您的意思是您希望控制整个过程以使其在例如 10 秒内发生吗?跨度>
  • 是的,我需要这样写,并不断重复尝试我的代码,然后 Mamoun 在 10 秒后弯下腰,但整个句子还没有完成!
  • @SaoudElTelawy,我更改了代码以将h3.innerHTML 的值设置为间隔超时时h3 的值,也许这会有所帮助?
【解决方案4】:

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

这是一个可重用的typewriter 函数示例,它接受元素、单词和间隔;并返回一个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>

要返回结果,你甚至可以promisify这个函数,它的优点是有一个异步错误的异常通道:

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))
&lt;h3 id="myh3"&gt;&lt;/h3&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多