首先,一些伪造的代码:
$("some-selector-logic").each(function() {
if (someLogic($(this))) {
return false;
}
// Otherwise do stuff related to $(this)
});
someMoreExcitingCode();
在这个例子中,我们基于一些选择器逻辑获得DOM元素的集合,然后迭代每个元素。对于我们称之为someLogic()
的每个元素。如果返回true
,我们将中止每个循环。否则,我们对元素执行一些逻辑,然后继续下一个元素。一旦我们完成了所有要素,我们就会继续并致电someMoreExcitingCode()
。
在调用someMoreExcitingCode()
之前,我想知道循环是否过早中止。显然你可以做这样的事情:
var aborted = false;
$("..").each(function() {
if (someLogic($(this))) {
aborted = true;
return false;
}
});
但这对我来说感觉很草率,就像jQuery应该以另一种方式向我提供这些信息。是否有一种更为惯用的方法来实现这一点,我不知道呢?
答案 0 :(得分:3)
由于jQuery函数倾向于返回相同的对象集合(允许链接),因此each()
函数无法将该信息返回给您 - 它已经返回了jQuery您可以将其他方法调用链接到的对象。
根据您提供的信息,我发现使用外部标记或计数器变量来获取此信息时没有问题。如果你告诉我们更多关于为什么你需要知道的事情,我们可能会提供更多有用的建议。
答案 1 :(得分:2)
$.each()
没有什么神奇之处。这是一个简单的功能,它可以满足您的需求,也可以不需要。如果没有,那么在代码示例中设置变量没有任何问题。编写自己的each()
函数可以完全满足您的需求。只需几行代码即可运行循环并调用您的回调函数。
以下是jQuery 1.10.1中$.each()
的源代码:
// args is for internal usage only
each: function( obj, callback, args ) {
var value,
i = 0,
length = obj.length,
isArray = isArraylike( obj );
if ( args ) {
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback.apply( obj[ i ], args );
if ( value === false ) {
break;
}
}
} else {
for ( i in obj ) {
value = callback.apply( obj[ i ], args );
if ( value === false ) {
break;
}
}
}
// A special, fast, case for the most common use of each
} else {
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback.call( obj[ i ], i, obj[ i ] );
if ( value === false ) {
break;
}
}
} else {
for ( i in obj ) {
value = callback.call( obj[ i ], i, obj[ i ] );
if ( value === false ) {
break;
}
}
}
}
return obj;
},
此代码中唯一的复杂性来自于它处理对象和数组的事实,每种情况都有两种不同的情况。
对于您正在处理的案例,可归结为:
for ( ; i < length; i++ ) {
value = callback.call( obj[ i ], i, obj[ i ] );
if ( value === false ) {
break;
}
}
那里没有那么多代码,如果不能做你想做的事,你可以轻松编写自己类似的迭代器,完全符合你的需要。
您甚至可以使用简单的for
循环。
function doExcitingStuff() {
var $elements = $("some-selector-logic");
for( var i = 0; i < $elements.length; i++ ) {
var $element = $($elements[i]);
if( someLogic($element) )
return;
// Otherwise do stuff related to $element
}
someMoreExcitingCode(); // only runs if the loop completes
}
这完全取决于是什么让你的代码最干净。您可以使用$.each()
或自己编写。
答案 2 :(得分:0)
可能没有您想要的那么优雅,但您可以使用Array.prototype.some
:
var aborted = Array.prototype.some.call($(".foo"), function(el) {
if ($(el).hasClass('bar')) {
return true;
}
});
答案 3 :(得分:0)
如果你真的,真的想避免使用abort
布尔值,并且你不关心效率,那么你可以这样做:
$("..").removeClass('aborted').each(function() {
if(someLogic($(this))) {
$(this).addClass('aborted');
return false;
}
});
if( $("..").find('aborted').length ) {
//each was aborted
}
else {
//each ran to completion
}
但这有效地使用DOM来注册你的布尔状态,而不是设置一个js var。
就个人而言,我会咬紧牙关并使用你的abort = true
想法。