为什么我的嵌套setTimeout延迟不起作用?

问题描述

当我在“ 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);
    }
  });

非常感谢, BadWoo

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

解决方法

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

,

如果您要做的是将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
}
<span id="changer2">repensent votre <span class='surlignement-rouge-text'>communication.</span></span>

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

var words = ["communication.","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,i+1),longInterval);
}

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