超时未按预期工作
timeout not working as expected
我试图让按钮从默认值 'this Will Change' 更改为 'New message',然后每 2 秒更改为 'someButton',然后停止它点击一下。
到目前为止,我有这个代码:
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>
它似乎忽略了第一个 setTimeout()
或者超时不是 运行 在新消息索引上。然后当我按下点击按钮时,没有超时被清除?
任何帮助我将不胜感激。
更新:我想尽可能保持 jQuery 的方向,谢谢!
之所以跳过new Message
是因为:
var someArray = {button: 'new Message', button: 'Some Btn'};
您的 someArray
是一个对象。因此,如果您有相同的 属性 名称,它将被覆盖并被解析为
var someArray = {button: 'Some Btn'};
只要使用合适的结构就可以了
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');
});
});
<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>
更新代码
我会这样写。基本变化很少,
- 使用
$(document).ready
作为代码流的开始。不作为您的代码的包装器。它应该调用必要的功能。
- 您应该使用
Array.map
、Array.forEach
而不是 $.each()
。这些功能非常强大和好用。
- 在任何函数之外定义的变量将成为全局范围的一部分。污染全局范围是一种不好的做法。
- 使用小功能。这样您就更有可能重用您的代码。任何可以在别处使用的代码都可以用作函数。
$(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');
});
}
<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>
您的用例准确描述了 setInterval 的用途。
"Repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. Returns an intervalID."
setInterval
函数 returns 一个 ID,可以将其传递到 clearInterval
以停止代码每 X 秒 执行一次。
我已经发布了一个代码片段来说明我认为你正在努力实现的目标。
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>
这是一种干净、实用的方法。纯属娱乐。
所选答案正确。我只是提供另一种选择,使用稍微不同的风格。
它启动、切换和停止。
// "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>
我试图让按钮从默认值 'this Will Change' 更改为 'New message',然后每 2 秒更改为 'someButton',然后停止它点击一下。
到目前为止,我有这个代码:
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>
它似乎忽略了第一个 setTimeout()
或者超时不是 运行 在新消息索引上。然后当我按下点击按钮时,没有超时被清除?
任何帮助我将不胜感激。
更新:我想尽可能保持 jQuery 的方向,谢谢!
之所以跳过new Message
是因为:
var someArray = {button: 'new Message', button: 'Some Btn'};
您的 someArray
是一个对象。因此,如果您有相同的 属性 名称,它将被覆盖并被解析为
var someArray = {button: 'Some Btn'};
只要使用合适的结构就可以了
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');
});
});
<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>
更新代码
我会这样写。基本变化很少,
- 使用
$(document).ready
作为代码流的开始。不作为您的代码的包装器。它应该调用必要的功能。 - 您应该使用
Array.map
、Array.forEach
而不是$.each()
。这些功能非常强大和好用。 - 在任何函数之外定义的变量将成为全局范围的一部分。污染全局范围是一种不好的做法。
- 使用小功能。这样您就更有可能重用您的代码。任何可以在别处使用的代码都可以用作函数。
$(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');
});
}
<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>
您的用例准确描述了 setInterval 的用途。
"Repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. Returns an intervalID."
setInterval
函数 returns 一个 ID,可以将其传递到 clearInterval
以停止代码每 X 秒 执行一次。
我已经发布了一个代码片段来说明我认为你正在努力实现的目标。
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>
这是一种干净、实用的方法。纯属娱乐。
所选答案正确。我只是提供另一种选择,使用稍微不同的风格。
它启动、切换和停止。
// "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>