我该如何解释setTimeout的这种行为?

时间:2015-08-31 23:18:20

标签: javascript jquery algorithm asynchronous responsive-design

我有一段代码

           var wsr = $('#work-sample-row');
            for (var i = 0, n = newRows.length; i < n; ++i)
            {
                var thisBox = box.clone();
                var thisNewRow = newRows[i];
                thisBox.find('.work-item-preview-outer').css('background-image', 'url(' + thisNewRow['imageurl'] + ')');
                thisBox.find('.work-title').text(thisNewRow['title']);
                thisBox.find('.work-descr-short').text(thisNewRow['sumsmall']);
                thisBox.find('.work-link-wrap').attr('href', siteUrl + '/our-work/ ' + workUrlPiece + '?id=' + thisNewRow['id']);
                wsr.append(thisBox); 
                setTimeout(function(){thisBox.css('opacity','1');}, i * 300);
            }     

用于将n个孩子添加到div,并通过opacity出现(以及CSS3 transition)来动画其外观,每个孩子之间的距离为300毫秒出现。但出于某种原因,它只适用于最后一个被添加的。所以我改为将代码的结尾改为

                //setTimeout(function(){thisBox.css('opacity','1');}, i * 300);
            }     
            k = 1;
            wsr.children().each(function(){
                var that = $(this);
                setTimeout(function(){that.css('opacity','1');}, (k++) * 300);
            });   

并且这很有效,但当然这是不优雅的,因为我每个人都会再次遍历这些元素。我怎样才能使第一种方式起作用?

1 个答案:

答案 0 :(得分:1)

那是因为当执行setTimeout回调时,thisBox变量引用最后一个克隆对象。 JavaScript(不是ECMAScript 2015)不支持块范围功能。

您可以使用与您的each回调类似的立即调用的函数创建新范围。

 for (var i = 0, n = newRows.length; i < n; ++i) {
    var thisBox = box.clone();
    // ...
    (function(box, index) {
        setTimeout(function(){ box.css('opacity','1');}, index * 300);
    })(thisBox, i);
 }