如何在.load()之后执行jQuery语句?

时间:2016-02-26 23:26:30

标签: javascript jquery

对不起可疑的问题标题。我不知道如何正确地说出来。请提供建议。

Anyhoo,我有这个HTML:

<ul class="image_reel">
<li class="thin"><a href="#" rel="img14" title="Click to view"><img   class="gal_thumb" src="8681.jpg"></a></li>
<li class=""><a href="#" rel="img0" title="Click to view"><img class="gal_thumb" src="DSC_7586.jpg"></a></li>
<li class="thin"><a href="#" rel="img2" title="Click to view"><img class="gal_thumb" src="DSC_7601.jpg"></a></li>
</ul>

我想根据子img的高度为li分配'thick'或'thin'类。所以我有这个jQuery:

 // add 'thin' class to parent li
 jQuery('.image_reel li a img').load( 
    function() {
            var t = jQuery(this);
            var h = this.naturalHeight;
            if( h < 800 ) {
                jQuery(t).parent().parent().addClass( 'thin' );
            }
 });                    

 // now sort lis
 var $images = jQuery('.image_reel');
 var $imagesli = $images.children('li');
 $imagesli.sort(function(a,b){
        var aT = jQuery(a).hasClass('thin');
        var bT = jQuery(b).hasClass('thin');
        if( aT == true && ( bT == false )  )
            return 1;
        else
            return 0;
 });
 $imagesli.detach().appendTo($images);       

问题似乎是第一个块似乎在第二个块之后执行。或者他们可能同步执行?无论如何,代码不起作用。那么......如何让第一个代码块执行-before-第二个?

奇怪的是,如果我使用Firefox'Q'调试器,代码实际上“有效”。但没有调试器它没有。我假设调试器强制代码以某种特殊顺序运行。

2 个答案:

答案 0 :(得分:2)

在一个函数中包装你的section块,然后在load函数结束后调用它,就像把它放在return中一样

// add 'thin' class to parent li
jQuery('.image_reel li a img').load(function() {
    var t = jQuery(this);
    var h = this.naturalHeight;
    if( h < 800 ) {
        jQuery(t).parent().parent().addClass( 'thin' );
    }
    return loadBlock();
});                    

function loadBlock() {
    // now sort lis
    var $images = jQuery('.image_reel');
    var $imagesli = $images.children('li');
    $imagesli.sort(function(a,b){
        var aT = jQuery(a).hasClass('thin');
        var bT = jQuery(b).hasClass('thin');
        if( aT == true && ( bT == false ) ) {
            return 1;
        } else {
            return 0;
        }
    });

    $imagesli.detach().appendTo($images);       
}

或使用async .waterfall.series

等软件包

你可以像我上面提到的那样使用像async这样的东西来对异步函数进行更好的流量控制,这里有一个关于如何避免调用每个回调的例子

async.each($("img"), function(e, callback) {
   $(this).load(function() {
      console.log("bdbdbd");
      callback(); // Done loading image
   });
}, function() {
   console.log("Done loading images");
   loadBlock();
});

如果使用得当,异步软件包可以并且将成为您最好的朋友。

我在移动设备上,所以我无法进行真正的测试,但这对jsbin工作得很好,只需将代码放在那里就可以了。

这是有效的,因为当你调用jQuery('.image_reel li a img').load时,它会在它找到的每个元素上运行自己的循环,并将事件监听器附加到它。

我使用的方法是使用async.each来获取数组,在这种情况下我提供了$(&#39;#img&#39;)作为数组,它将是它找到的任何元素的集合与查询匹配,然后async.each将并行运行循环,因此我们不必等待一个循环完成循环才能进入下一个循环。

然后在循环体中,我们在.load上调用.this,它一次只在一个元素上附加.load函数,而不是试图在所有的元素上执行自己的内部循环因此,当函数完成时,我们知道它的完成导致该函数仅在元素上运行。然后我们调用callback(); async.each.eachcallback知道函数体已完成并且可以继续,当所有循环触发它们.each循环结束时然后执行main函数(该函数是MATCH p=allShortestPaths( (a:Item {itemId:"Q6294"})-[*]-(b:Item {itemId:"Q359442"}) ) WHERE NONE(x IN NODES(p) WHERE x:Item AND x.itemId = "Q5") RETURN p; 的第三个参数)。您可以在此处查看有关async.each的更多信息:async.each

答案 1 :(得分:1)

第二个块在第一个块之前执行,因为load()立即解析,并且仅在完成后稍后调用第一个块。要执行您想要的操作,请在第一个块的末尾调用第二个块。

// add 'thin' class to parent li
 jQuery('.image_reel li a img').load( 
    function() {
            var t = jQuery(this);
            var h = this.naturalHeight;
            if( h < 800 ) {
                jQuery(t).parent().parent().addClass( 'thin' );
            }
            doWork();
 });                    

function doWork() {
 // now sort lis
 var $images = jQuery('.image_reel');
 var $imagesli = $images.children('li');
 $imagesli.sort(function(a,b){
        var aT = jQuery(a).hasClass('thin');
        var bT = jQuery(b).hasClass('thin');
        if( aT == true && ( bT == false )  )
            return 1;
        else
            return 0;
 });
 $imagesli.detach().appendTo($images); 
}