超时未按预期工作

时间:2016-12-08 05:09:51

标签: javascript jquery html timeout

我正试图让按钮更改默认设置'这将改变'然后改变它所说的内容'新消息'然后回到&some; Button'每2秒钟然后点击一下就停止它。

到目前为止,我有这段代码:



var timeouts = [];

var someArray = {button: 'new Message', button: 'Some Btn'};

$(document).ready(function(){
var i = 2000;
$.each(someArray, function(index, value){
    timeouts.push(setTimeout(function(){
          $(index).html(value);
     },i));
     i = i + 2000;
});


$('#stop').click(function(){
    $.each(timeouts, function (_, id) {
       clearTimeout(id);
    });
    timeouts = [];
    $(button).html('Some Btn');
});
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type='button'>
This will change
</button>
<a id='stop' href='#'>Stop</a>
&#13;
&#13;
&#13;

似乎忽略了第一个setTimeout()或者没有在新邮件索引上运行超时..然后当我按下单击按钮时,没有超时被清除?

在我出错的地方,我们将非常感谢任何帮助。

更新:我希望尽可能保持jQuery的面向,谢谢!

3 个答案:

答案 0 :(得分:2)

它跳过new Message的原因是:

var someArray = {button: 'new Message', button: 'Some Btn'};

您的someArray是一个对象。因此,如果您具有相同的属性名称,它将被覆盖,并将被解析为

var someArray = {button: 'Some Btn'};

只需使用适当的结构,它应该可以正常工作

&#13;
&#13;
var timeouts = [];

var someArray = [{
  type: "button",
  message: 'new Message',
}, {
  type: "button",
  message: 'Some Btn'
}];

$(document).ready(function() {
  var i = 2000;
  $.each(someArray, function(index, value) {
    timeouts.push(setTimeout(function() {
      $(value.type).html(value.message);
    }, i));
    i = i + 2000;
  });


  $('#stop').click(function() {
    $.each(timeouts, function(_, id) {
      clearTimeout(id);
    });
    timeouts = [];
    $(button).html('Some Btn');
  });
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type='button'>
  This will change
</button>
<a id='stop' href='#'>Stop</a>
&#13;
&#13;
&#13;

更新了代码

这就是我写的方式。几个基本的变化,

  • 使用$(document).ready作为代码流的开头。不是代码的包装器。它应该调用必要的功能。
  • 您应该使用Array.mapArray.forEach代替$.each()。这些功能非常强大且方便。
  • 在任何函数之外定义的变量将是全局范围的一部分。污染全球范围是一种不好的做法。
  • 使用小功能。这样,您可以重用代码的可能性更高。任何可以在其他地方使用的代码都可以用作函数。

&#13;
&#13;
$(document).ready(function() {
  var someArray = [
    { type: "button", message: 'new Message', }, 
    { type: "button", message: 'Some Btn' }
  ];

  var timeouts = registerTimeouts(someArray);
  registerEvents(timeouts)
});

function registerTimeouts(array) {
  return array.map(function(value, index) {
    return setTimeout(function() {
      $(value.type).html(value.message);
    }, (index + 1) * 2000);
  });
}

function registerEvents(timeouts) {
  $('#stop').click(function() {
    timeouts.forEach(function(id) {
      clearTimeout(id);
    });
    timeouts = [];
    $(button).html('Some Btn');
  });
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type='button'>
  This will change
</button>
<a id='stop' href='#'>Stop</a>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

您的用例确切地描述了setInterval的用途。

  

“重复调用函数或执行代码片段,每次调用之间有固定的时间延迟。返回intervalID。”

setInterval函数返回一个ID,可以将其传递到clearInterval以阻止代码每 X秒执行

我已经发布了一个代码片段给我认为你想要实现的目标。

Plnkr Link

var strings = ["This will change", "Some button"];
var intervalID;
var button;
var index = 0;

$(document).ready(function() {
  button = $("#myButton");
  intervalID = window.setInterval(function() {
    console.log("hi");
    button.html(strings[index]);
    index = (index == 1 ? 0 : 1);
  }, 2000);
  $("#stop").click(function() {
    window.clearInterval(intervalID);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="myButton" type='button'>
  This will change
</button>
<a id='stop' href='#'>Stop</a>

答案 2 :(得分:1)

这是一种干净,实用的方式。只是为了好玩。

所选答案现场点亮。我只是提供另一种选择,使用略有不同的风格。

启动,切换和停止。

// "constant" array of messages
var messagesArray = ['new Message', 'Some Btn'];

// original button text
var btnOrigText = $('button').text()

// reverse an array
var _arrReverse = function(arr) {
    return arr.reverse()
}

// insert text from array 0th index into an element
var _insertTextArrayZero = function(el, messages) {
    // inserts an array's 0th index as HTML to an element
    return $(el).html(messages[0]);
}

// clears a timeout when given an id
var _clearIntvlAt = function(intvlId) {
    return clearTimeout(intvlId);	
}

$(document).ready(function(){
    // set interval
    var intvl = 2000;
    // keep our original array intact
    var messagesCloned = messagesArray.slice(0)
    // run interval
    var toggleTextIntvl = setInterval(function() {
    	// insert reversed array from [0] index of array into HTML element
        // NOTE: this only works for arrays of 2 items which need to toggle
    	return _insertTextArrayZero('button', _arrReverse(messagesCloned))
    }, intvl);
     
    // initiate "stopping" of toggle text
    $('#stop').click(function() {
        // stop toggleTextIntvl
        _clearIntvlAt(toggleTextIntvl)
        // set markup back to default
        $('button').html(btnOrigText);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type='button'>
This will change
</button>
<a id='stop' href='#'>Stop</a>