【问题标题】:jquery .each loop to execute each array item with a delay between themjquery .each 循环执行每个数组项,它们之间有延迟
【发布时间】:2016-04-22 16:52:30
【问题描述】:

请帮忙!我正在制作一个同时触发多个警报的警报系统,但我实际上希望它们一次出现一个,以便它看起来像 bash 中的命令提示符,它是睡眠功能。

看看https://jsfiddle.net/14cmgrLj/10/

  function iterateThru (message, status) {
    var time = 500;
    $.each(alertsArray, function(index, item) {
    		
      	//setTimeout(function(){ fireAlerts(message, status); }, 1000);
        setTimeout(fireAlerts, 100, message, status);
				
        //remove
				setTimeout(removeAlert, 4000);
    });  
    // empty array
    alertsArray = [];
  }

我从我的网站各处调用此函数。为了使它们逐一触发-每次使用我的函数时,都会将对象添加到数组中,然后我使用 .each 使用 setTimeout 循环遍历它们中的每一个,但它们仍然会一次全部触发。我怎样才能循环遍历数组的项目,每个项目之间都有延迟。

提前致谢

【问题讨论】:

  • 您的 fireAlert 和 removeAlert 功能是否按预期工作>
  • setTimeouts 会导致您的代码异步运行,这就是导致问题的原因。您需要改用递归循环。
  • FireAlert 和 removeAlert 函数可以工作,但不是我想要的方式。 jsfiddle.net/14cmgrLj/10@ayushgp

标签: javascript jquery html css alert


【解决方案1】:

你可以使用jQuery的.delay函数来管理队列jQuery: Can I call delay() between addClass() and such?


或者……

对循环中的每条消息使用IIFE to manage the incremental wait

小提琴:https://jsfiddle.net/14cmgrLj/11/

它需要更多的工作,因为如果您在第一组完成后但在它们被隐藏之前单击创建警报按钮,那么时间会很糟糕。

function fireAlerts(alerts) {      
  $.each(alerts, function(index, value) {
    // Use IIFE to multiply Wait x Index
    (function(index, value) {
      var wait = index * 1000 + 1000;
      setTimeout(function() {
        // Show Alert
        // [...]
        }
      }, wait);
    })(index, value);
  });
}

【讨论】:

  • 你是个天才!我很羡慕你的知识!谢谢jsfiddle.net/14cmgrLj/12
  • 关于如何使用参数来决定顺序或重要性级别的任何想法? @贾斯汀
  • 您可以使用弹性框 order 属性来设置我相信的顺序:stackoverflow.com/a/28159766/922522
  • 您是否在页面加载时添加所有警报并且从不更改它们?
【解决方案2】:

如前所述,setTimeout 只是安排任务并立即返回。所以使用这样的东西:

<script>
var alertArray=[];
function showAlert(){
    var al = alertArray.shift();// removes and return first element
    if(al !== undefined){
        alert(al);
    }
    setTimeout(showAlert, 4000);
}
setTimeout(showAlert, 4000);
function addAlert(al){
    alertArray.push(al);//add new alert to the end
}
</script>

【讨论】:

    【解决方案3】:

    好的,所以我在您的代码中发现了问题。 setTimeout 函数在给定时间后调用函数内部编写的代码。但是是异步的,即它不会阻塞。因此,当您遍历每个元素时,会调用函数,这三个函数几乎同时调用(您给它们提供了相同的超时时间)。您需要做的是定义一个新变量(每行出现的时间 b/w)并在每次迭代中递增它。

    function iterateThru (message, status) {
        var time = 0;
        $.each(alertsArray, function(index, item) {
    
            setTimeout(function(){ 
                fireAlerts(message, status); 
            }, time);
            time += 1000;
    
            //remove
            setTimeout(removeAlert, 4000);  //Change value of 4000 accordingly.
        });  
        // empty array
        alertsArray = [];
      }
    

    【讨论】:

      【解决方案4】:

      你写东西的方式是做一些奇怪的事情,所以我对你的解决方案进行了这个改变:

      • 使用从 jQuery Deferred 创建的“等待”函数添加警报屏幕
      • 如果需要,将警报添加到数组(取消注释)
      • 我将您的全局变量移到名为 myApp 的命名空间中。

      在这里试试:https://jsfiddle.net/MarkSchultheiss/14cmgrLj/14/

      修改后的代码:

      //create app or use one if exists
      var myApp = myApp || {};
      // add alerts data
      myApp.alerts = {
        count: 0,
        alertDelay: 3000,
        defaultStatus: "1",
        alertsArray: []
      };
      myApp.func = {
        wait: function(ms) {
          var defer = $.Deferred();
          setTimeout(function() {
            defer.resolve();
          }, ms);
          return defer;
        },
        addAlert: function(message, status) {
          status = status || myApp.alerts.defaultStatus;
          myApp.alerts.count++; // counts how many have ran
          var alert = [message, status, myApp.alerts.count];
          // uncomment if you need keep track of them:
          // myApp.alerts.alertsArray.push(alert);
          myApp.func.fireAlert(alert, myApp.alerts.alertDelay);
        },
        fireAlert: function(item, delay, index) {
          $("#terminal").append("<span class='d" + item[2] + "'>" + item[0] + "</span><br />");
          myApp.func.wait(delay).then(function() {
            $("#terminal").find('.d' + item[2]).addClass('fadeOutDown');
          })
        }
      };
      //====== Trigger ======//
      $("#trigger").click(function(event) {
        console.log("There have been " + myApp.alerts.count + " alerts ran");
        console.log(myApp.alerts.alertsArray);
        myApp.func.addAlert($('#field').val(), 2);
        myApp.func.addAlert($('#field').val(), 2);
        myApp.func.addAlert($('#field').val(), 2);
      });
      

      【讨论】:

        猜你喜欢
        • 2014-01-08
        • 2015-06-15
        • 2013-01-25
        • 2022-07-19
        • 1970-01-01
        • 2011-09-15
        • 2011-11-18
        • 2012-09-22
        • 1970-01-01
        相关资源
        最近更新 更多