减少设置超时的次数

时间:2019-07-15 14:52:27

标签: javascript settimeout

我正在为每个具有类循环字的元素创建一个新的setTimeout。他们没有理由不能全部使用相同的setTimeout,但是我不确定如何实现:

    var cycles = document.getElementsByClassName("cycle-words");
    
    for (var i = 0; i < cycles.length; i++) {
     createCycle(cycles[i]);
    }
    
    function createCycle(element) {
      var wordsCnt = 0;
      var words = element.getAttribute("data-words").split(",");
     
      setTimeout(function showWord() {
        element.innerHTML = words[wordsCnt];
        wordsCnt = (wordsCnt + 1) % words.length;
        setTimeout(showWord, 500);
      }, 500);
    }
<div class="cycle-words" data-words="yes,no,maybe"></div>


<div class="cycle-words" data-words="hello,hi,hey"></div>

我只希望对cycle-words类的所有元素使用一个setTimeout。

5 个答案:

答案 0 :(得分:0)

您可以使用setInterval(),因此只有1个代码块。 setTimeout只会运行一次,但是setInterval会运行直到您用clearInterval停止运行。

在此示例中,我还将单词计数移动到每个元素的数据属性中,以使它们不依赖于具有相同数量的单词(我在问候词中添加了“ Yo!”,作为例如)。

var cycles = document.getElementsByClassName("cycle-words");

setInterval(cycleWords, 500);

function cycleWords() {
    for (var i = 0; i < cycles.length; i++) {
        var element = cycles[i];

        // get the current wordsCnt value for this element
        var wordsCnt = parseInt(element.getAttribute("data-word-count") || 0, 10);

        var words = element.getAttribute("data-words").split(",");

        // set the text of the element            
        element.textContent = words[wordsCnt];

        // increment and set the wordsCnt attribute value for next time
        wordsCnt = (wordsCnt + 1) % words.length;
        element.setAttribute("data-word-count", wordsCnt);
    }
}
<div class="cycle-words" data-words="yes,no,maybe"></div>
<div class="cycle-words" data-words="hello,hi,hey,yo!"></div>

答案 1 :(得分:0)

通过将所有元素传递到一个开始循环的函数,您可以只使用1个"laravel/cashier": "^9.3",

setTimeout
function cycler(elements)
{
    setTimeout(function showWord() {
        for(var i = 0; i<elements.length;i++)
        {
            var element = elements[i];
            var words = element.getAttribute("data-words").split(",");
            var wordsCnt = element.wordsCnt || 0;
            element.innerHTML = words[wordsCnt];
            element.wordsCnt = (wordsCnt + 1) % words.length;
        }
        setTimeout(showWord, 500);
      }, 500);
}
var cycles = document.getElementsByClassName("cycle-words");
cycler(cycles);

答案 2 :(得分:0)

您可以将showWord函数存储在数组中,然后在每个setTimeout上循环该数组。

同样要提防,如果要访问数据属性,还可以执行-> element.dataset.words,所有主流浏览器都支持。

下面是修改您的代码以执行此操作的方法->

var cycles = document.getElementsByClassName("cycle-words");

function createCycle(element) {
  var wordsCnt = 0;
  var words = element.dataset.words.split(",");
  function showWord() {
    element.innerHTML = words[wordsCnt];
    wordsCnt = (wordsCnt + 1) % words.length;
  }
  return showWord;
}

var showWordsFn = [];
for (var i = 0; i < cycles.length; i++) {
  showWordsFn.push(createCycle(cycles[i]));
}

function showWords() {
  for (var i = 0; i < showWordsFn.length; i += 1)
    showWordsFn[i]();
  setTimeout(showWords, 500);
}

showWords();
<div class="cycle-words" data-words="yes,no,maybe"></div>


<div class="cycle-words" data-words="hello,hi,hey"></div>

答案 3 :(得分:-1)

setTimeout是一个函数 将其定义为

var s= setTimeout(function showWord() {
        element.innerHTML = words[wordsCnt];
        wordsCnt = (wordsCnt + 1) % words.length;
        setTimeout(showWord, 500);
      }, 500);

作为全局变量,并在需要时传递

答案 4 :(得分:-1)

为什么要完全使用setTimeout()?可以使用单个setInterval()函数来完成。假设您只有2个div或更多,请在单独的变量中获取div的数据,然后获取它们的值,合并结果数组,并为每个数组中的 setInterval() 功能。

生成的代码比其他代码更简单。我在下面的评论中添加了额外的信息。

let cycles = document.querySelector(".cycle-words") // first div
let cycles2 = document.querySelector(".cycle-words2") // second div
let arr1 = cycles.getAttribute("data-words").split(",") // first div's data in array 
let arr2 = cycles2.getAttribute("data-words").split(",") // second div's data in array 
// merge the array and then forEach
let i = 0
setInterval(() => { // set the interval
  let lim = Math.max(arr2.length,arr1.length) // get the maximum array length

  if (lim != i && arr1[i] && arr2[i]) { // check if value exists
    cycles.innerHTML = arr1[i] // add the values
    cycles2.innerHTML = arr2[i] // same here
  }
  i++ // increment i 
  if (lim == i) { // check if the lim is passed if it is then reset it
    i = 0
  }
}, 500)
<div class="cycle-words" data-words="yes,no,maybe"></div>
<div class="cycle-words2" data-words="hello,hi,hey"></div>

相关问题