Thought I had this in the bag...guess I was wrong:
以为我把它放在包里......猜我错了:
Expected behavior - page loads, then for each element in the array it updates my innerHTML value using setTimeout
预期的行为 - 页面加载,然后对于数组中的每个元素,它使用setTimeout更新我的innerHTML值
Observed behavior - On my hosting it seems to update the value just one time, then it breaks my css before becoming unresponsive. I threw in an alert to see if it's ever running on jsFiddle and it appears to not be running so there's also that ????
观察到的行为 - 在我的托管上它似乎只更新了一次值,然后它在没有响应之前打破了我的CSS。我发出警报,看看它是否曾在jsFiddle上运行,它似乎没有运行,所以还有那个????
The markup:
<button type="button" id="ctaButton" class="cta btn btn-lg btn-success pulsate" data-keyboard="true" data-toggle="modal" data-target="#contactUs">Get Started Today</button>
The JS:
$(warmup());
function warmup(){
//sanity check
confirm("working???");
setTimeout(changeCTAtext, 3000);
}
function changeCTAtext(){
var ctaList = [ 'Complementary Quotes', 'Book Your Consultation', 'Get Started Today' ];
var myField = document.getElementById("ctaButton");
while (true){
for (var i = 0; i<ctaList.length, i++;){
setTimeout('myField.innerHTML = ctaList[i];', 1000);
};
};
};
and here is the mandatory fiddle as usually requested.
这是通常要求的强制性小提琴。
2 个解决方案
#1
1
There's absolutely no need to set synchronous multiple timeouts inside a loop.
Use only a single setInterval
or recall a function than has a single setTimeout
绝对不需要在循环内设置同步多个超时。仅使用一个setInterval或调用一个函数而不是一个setTimeout
You could easily do this using setInterval()
If you want to make your code simpler (without the iterations counter) you could just manipulate the Array like:
如果你想让你的代码更简单(没有迭代计数器),你可以像以下一样操纵数组:
jQuery(function($){
var $btn = $("#ctaButton"),
ctaList = ['Get Started Today', 'Complementary Quotes', 'Book Your Consultation'];
function changeCTAtext(){
ctaList.push( ctaList.shift() ); // manipulate
$btn.html( ctaList[0] ); // and use always the [0]th index
};
setInterval(changeCTAtext, 1000); // Start
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="ctaButton">Get Started Today</button>
usign a c
counter and loop using ++c % array.length
jQuery(function($){
var $btn = $("#ctaButton"),
ctaList = ['Get Started Today', 'Complementary Quotes', 'Book Your Consultation'],
tot = ctaList.length,
c = 0; // iterations counter
function changeCTAtext(){
$btn.html( ctaList[++c%tot] );
};
setInterval(changeCTAtext, 1000); // Start
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="ctaButton">Get Started Today</button>
Using setTimeout()
it's like this:
使用setTimeout()就像这样:
jQuery(function($){
var $btn = $("#ctaButton"),
ctaList = ['Get Started Today', 'Complementary Quotes', 'Book Your Consultation'],
tot = ctaList.length,
c = 0; // iterations counter
function changeCTAtext(){
$btn.html( ctaList[c++%tot] );
setTimeout(changeCTAtext, 1000); // ...and repeat every NNNms
};
changeCTAtext(); // Start
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="ctaButton">Get Started Today</button>
#2
1
I found two mistakes in your code:
我在你的代码中发现了两个错误:
-
setTimeout
first param should be a function. So it should be written as follows
setTimeout第一个param应该是一个函数。所以应该写成如下
setTimeout(changeCTAtext, 3000);
and
while (true){
for (var i = 0; i < ctaList.length; i++){
setTimeout(function(){myField.innerHTML = ctaList[i]}, 1000);
};
};
- When you use the iterated index of a for loop inside a timeout, when the timeout ends the index has already changed. Thus you need to bind the index in each iteration. There are several fixes for this, one of them is placing the timeout inside an IIFE with the index as closure:
当您在超时内使用for循环的迭代索引时,超时结束时索引已经更改。因此,您需要在每次迭代中绑定索引。有几个修复,其中一个是将超时放在IIFE中,索引为闭包:
.
for (var i=0; i < ctaList.length; i++) {
(setTimeout(function(i) {myField.innerHTML = ctaList[i]}, 1000)(i);
}
#1
1
There's absolutely no need to set synchronous multiple timeouts inside a loop.
Use only a single setInterval
or recall a function than has a single setTimeout
绝对不需要在循环内设置同步多个超时。仅使用一个setInterval或调用一个函数而不是一个setTimeout
You could easily do this using setInterval()
If you want to make your code simpler (without the iterations counter) you could just manipulate the Array like:
如果你想让你的代码更简单(没有迭代计数器),你可以像以下一样操纵数组:
jQuery(function($){
var $btn = $("#ctaButton"),
ctaList = ['Get Started Today', 'Complementary Quotes', 'Book Your Consultation'];
function changeCTAtext(){
ctaList.push( ctaList.shift() ); // manipulate
$btn.html( ctaList[0] ); // and use always the [0]th index
};
setInterval(changeCTAtext, 1000); // Start
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="ctaButton">Get Started Today</button>
usign a c
counter and loop using ++c % array.length
jQuery(function($){
var $btn = $("#ctaButton"),
ctaList = ['Get Started Today', 'Complementary Quotes', 'Book Your Consultation'],
tot = ctaList.length,
c = 0; // iterations counter
function changeCTAtext(){
$btn.html( ctaList[++c%tot] );
};
setInterval(changeCTAtext, 1000); // Start
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="ctaButton">Get Started Today</button>
Using setTimeout()
it's like this:
使用setTimeout()就像这样:
jQuery(function($){
var $btn = $("#ctaButton"),
ctaList = ['Get Started Today', 'Complementary Quotes', 'Book Your Consultation'],
tot = ctaList.length,
c = 0; // iterations counter
function changeCTAtext(){
$btn.html( ctaList[c++%tot] );
setTimeout(changeCTAtext, 1000); // ...and repeat every NNNms
};
changeCTAtext(); // Start
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="ctaButton">Get Started Today</button>
#2
1
I found two mistakes in your code:
我在你的代码中发现了两个错误:
-
setTimeout
first param should be a function. So it should be written as follows
setTimeout第一个param应该是一个函数。所以应该写成如下
setTimeout(changeCTAtext, 3000);
and
while (true){
for (var i = 0; i < ctaList.length; i++){
setTimeout(function(){myField.innerHTML = ctaList[i]}, 1000);
};
};
- When you use the iterated index of a for loop inside a timeout, when the timeout ends the index has already changed. Thus you need to bind the index in each iteration. There are several fixes for this, one of them is placing the timeout inside an IIFE with the index as closure:
当您在超时内使用for循环的迭代索引时,超时结束时索引已经更改。因此,您需要在每次迭代中绑定索引。有几个修复,其中一个是将超时放在IIFE中,索引为闭包:
.
for (var i=0; i < ctaList.length; i++) {
(setTimeout(function(i) {myField.innerHTML = ctaList[i]}, 1000)(i);
}