【问题标题】:why my nested setTimeout delay not working?为什么我的嵌套 setTimeout 延迟不起作用?
【发布时间】:2020-09-08 09:40:58
【问题描述】:

当我滚动“frame-2”元素时,我想每 300 毫秒更改一次单词。该单词每 300 毫秒更改一次,并在我的数组的每个单词上停止。

滚动功能有效。每个单词的停止也有效,但延迟不是 300 毫秒不被尊重,单词几乎立即改变。您是否看到了我没有看到的错误?

function interval(func, wait, times){
    var interv = function(w, t){
      return function(){
        if(typeof t === "undefined" || t-- > 0){
          setTimeout(interv, w);
          try{
            func.call(null);
          }
          catch(e){
            t = 0;
            throw e.toString();
          }
        }
      };
    }(wait, times);

    setTimeout(interv, wait);
  };

  var words21 = ["communication.", "image.", "concept.", "référencement.", "stratégie.", "contenu.", "social média."];
  var text21 = "repensent votre <span class='surlignement-rouge-text'>communication.</span>";
  var i21;
  var wi21;

  function _getChangedText21() {
    i21 = (i21 + 1);
    if (words21[i21] != undefined) {
      return text21.replace(/communication./, words21[i21]);
    } else {
      return text21.replace(/communication./, words21[wi21]);
      wi21 = (wi21 + 1);
    }
  }

  $(window).scroll(function() {
    text21.replace(/communication./, words21[0]);
    i21 = 0;
    wi21 = 1;
    x = 0;
    var hT20 = $('#frame-2').offset().top,
        hH20 = $('#frame-2').outerHeight(),
        wH20 = $(window).height(),
        wS20 = $(this).scrollTop();

    if (wS20 > (hT20+hH20-wH20)) {
      interval(function _getInterval21() {
        interval(function _changeText21() {
          var txt21 = _getChangedText21();
          document.getElementById("changer2").innerHTML = txt21;
        }, 300, 8);
        selectwords21 = words21[0];
        words21.shift();
        words21.push(selectwords21);
      }, 2000, 6);
      selectwords21 = words21[0];
      words21.shift();
      words21.push(selectwords21);
      selectwords21 = words21[0];
      words21.shift();
      words21.push(selectwords21);
    }
  });

非常感谢, 坏人

编辑:这是一个 codepen 示例:https://codepen.io/BadWoo/pen/MWyQbPB

【问题讨论】:

  • 这行setTimeout(interv2, w); 是做什么的?看起来它应该是某种递归,但 interv2 函数无处可见,这是一个错字吗?
  • “几乎”是什么意思? 300 毫秒是 1/3 秒,在我看来它“几乎”是瞬间的..
  • @KrzysztofKrzeszewski 谢谢你,这是一个拼写错误。我编辑我的问题。
  • @Kaddath 300ms 很快,但文字变化更快,当我改变这个值时,比如 1000ms,延迟不会改变 --'
  • 请提供minimal reproducible example - 就目前而言,很难看出您的问题发生了什么。您的 interval 函数工作正常(通过传递 func 轻松验证,它只是将当前时间记录到控制台)

标签: javascript jquery settimeout


【解决方案1】:

如果您只想更改 changer2 中的文本以替换“通信”的单词轮换列表。你可以在几行代码中做到这一点(见下面的例子)。

  • 无需不断移动和推动单词——只需使用模运算符%
  • 无需嵌套调用setTimout - 使用setInterval

假设我已经正确理解了你想要达到的目标,这里是工作代码(根据需要调整时间):

function changeWords(){

  var words = ["communication.", "image.", "concept.", "référencement.", "stratégie.", "contenu.", "social média."];
  var i = 1;
  setInterval( () => {
    document.querySelector('.surlignement-rouge-text').innerHTML = words[i++ % words.length];
  }, 1000);

}

// You could call this from your scroll handler!
changeWords();
.surlignement-rouge-text{
    color: red
}
&lt;span id="changer2"&gt;repensent votre &lt;span class='surlignement-rouge-text'&gt;communication.&lt;/span&gt;&lt;/span&gt;

进一步了解您的要求后,似乎代码确实需要稍微复杂一点,但不要太多!

var words = ["communication.", "image.", "concept.", "référencement.", "stratégie.", "contenu.", "social média."];

async function changeWords(interval){

  return new Promise( resolve => {
  
    var i = 0;
    var timer = setInterval( () => {
      document.querySelector('.surlignement-rouge-text').innerHTML = words[i++];
      if(i == words.length){
        clearInterval(timer);
        resolve();
      }
    }, interval);
  });
}

async function cycleWords(shortInterval, longInterval, i){
  await changeWords(shortInterval);
  document.querySelector('.surlignement-rouge-text').innerHTML = words[i % words.length];
  setTimeout(() => cycleWords(shortInterval,longInterval, i+1),longInterval);
}

// You could call this from your scroll handler!
cycleWords(300,2000,0);
.surlignement-rouge-text{
    color: red
}
&lt;span id="changer2"&gt;repensent votre &lt;span class='surlignement-rouge-text'&gt;communication.&lt;/span&gt;&lt;/span&gt;

【讨论】:

    【解决方案2】:

    首先t 永远不会是"undefined",但它可以是undefined。其次,不要调用setTimeout(interv, wait),而是调用setTimeout(interv(), wait),因为interv 返回一个函数,而这正是你想要执行的。

    【讨论】:

    • 两点都错了,不是t === undefined而是typeof,它返回一个字符串。 interv 的函数以 }(wait, times); 结尾,所以它是一个 IIFE,它会立即使用这些参数执行,这是函数记住本地值的一种方式(因为 setTimeout 在全局上下文中触发)
    猜你喜欢
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多