对不起可疑的问题标题。我不知道如何正确地说出来。请提供建议。
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'调试器,代码实际上“有效”。但没有调试器它没有。我假设调试器强制代码以某种特殊顺序运行。
答案 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
,.each
让callback
知道函数体已完成并且可以继续,当所有循环触发它们.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);
}