[英]SetTimeout inside a for loop
我正在嘗試編寫一個可更改3張圖像的z-index的腳本。 基本上,腳本應以當前圖片為目標,並在下一張圖片上應用更高的Z索引,就像輪播一樣,但具有Z索引而不是活動類。 挑戰在於在特定間隔后設置z-index。 問題在於顯示的是第一個圖像,然后是最后一個。 這是我的代碼:
HTML:
<div class="changingimages">
<img src="#" data-time="3000" width="100%" class="alternateimage alternateimage1">
<img src="#" data-time="2000" width="100%" class="alternateimage alternateimage2">
<img src="#" data-time="4000" width="100%" class="alternateimage alternateimage3">
</div>
jQuery腳本
<script type="text/javascript">
jQuery(document).ready(function(){
var changeImg = function(i, time, currentImg) {
setTimeout(function(){
jQuery(currentImg).next().css("z-index", i);
}, time);
};
var numberOfChilds = jQuery(".changingimages").children().length;
var currentIndexClass;
var currentImg;
var time;
for (var i=1; i<=numberOfChilds; i++) {
currentIndexClass = '.alternateimage' + i;
currentImg = jQuery(currentIndexClass);
time = jQuery(currentIndexClass).attr("data-time");
changeImg(i, time, currentImg);
}
});
我認為循環中的閉包存在一些問題,但不確定!
常見的誤解是setTimeout
將事件安排為相對於先前排隊的事件運行。 從理論上講,您似乎相信以下內容:
setTimeout(f, 100);
setTimeout(g, 100);
setTimeout(h, 100);
會導致這樣的時間軸:
0ms Start
100ms Run f()
200ms Run g()
300ms Run h()
現實情況是setTimeout
中的time選項表示“至少在經過這么多時間后運行此函數”。 從上一個示例來看,您實際上會得到更多類似的信息
0ms Start
100ms Run f()
101ms Run g()
102ms Run h()
為了正確地分隔代碼,請繼續增加超時時間,而不是替換超時時間。
var time = 0;
for (var i = 1; i <= numberOfChilds; i++) {
currentIndexClass = '.alternateimage' + i;
currentImg = jQuery(currentIndexClass);
// Add to the previous time
time += parseInt(jQuery(currentIndexClass).attr("data-time"), 10);
changeImg(i, time, currentImg);
}
這是一個小工具,實現了使用超時來實現所需的功能。
.textArea {
position: absolute;
height: 50px;
width: 50px;
display: block;
}
.box_a {
background-color: blue;
}
.box_b {
background-color: red;
}
.box_c {
background-color: orange;
}
.active {
z-index: 3;
}
<div class="textArea box_a active">a</div>
<div class="textArea box_b">b</div>
<div class="textArea box_c">c</div>
$(function(){
var $elem = $('.textArea');
timeout(0);
function timeout(i){
$($elem[i]).addClass('active');
return setTimeout(function(){
$elem.removeClass('active');
i++;
if(i >= $elem.length){
i = 0
}
timeout(i);
}, 1000)
}
});
請注意,它不使用for循環,因為超時是異步的,不會順序執行。 基本上每個超時都會在同一時間觸發,然后根據等待時間執行其操作。
解決方案是創建一個跟蹤索引以及上次超時何時完成執行的函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.