嵌套的jQuery.each() – 继续/中断

考虑下面的代码:

var sentences = [ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'Vivamus aliquet nisl quis velit ornare tempor.', 'Cras sit amet neque ante, eu ultrices est.', 'Integer id lectus id nunc venenatis gravida nec eget dolor.', 'Suspendisse imperdiet turpis ut justo ultricies a aliquet tortor ultrices.' ]; var words = ['ipsum', 'amet', 'elit']; $(sentences).each(function() { var s = this; alert(s); $(words).each(function(i) { if (s.indexOf(this) > -1) { alert('found ' + this); return false; } }); }); 

有趣的部分是嵌套的jQuery.each()循环。 根据文档 ,返回false将跳出循环(中断循环的执行 – 类似于正常的JavaScript break语句),并且返回非false将停止当前迭代并继续下一次迭代(类似于正常JavaScript继续声明)。

我可以打破或继续自己的jQuery.each(),但嵌套的jQuery.each,我发现很难摆脱子循环内的父循环。 我可以使用一个布尔值,并更新每个子迭代,但我想知道是否有一个更简单的方法。

我已经在jsFiddle上build立了一个例子,如果你想搞砸它。 只需点击“testing”button来运行上面的示例。

TLDR:在jQuery的上下文中是否有类似标签的继续或断开?

你应该这样做, 没有 jQuery,它可能不是“漂亮”,但没有那么多,而且更容易做到你想要的,就像这样:

 var sentences = [ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'Vivamus aliquet nisl quis velit ornare tempor.', 'Cras sit amet neque ante, eu ultrices est.', 'Integer id lectus id nunc venenatis gravida nec eget dolor.', 'Suspendisse imperdiet turpis ut justo ultricies a aliquet tortor ultrices.' ]; var words = ['ipsum', 'amet', 'elit']; for(var s=0; s<sentences.length; s++) { alert(sentences[s]); for(var w=0; w<words.length; w++) { if(sentences[s].indexOf(words[w]) > -1) { alert('found ' + words[w]); return; } } } 

你可以在这里试试 。 我不确定这是否是确切的行为,但是现在你不在由double .each()创build的闭包中的闭包中,并且在这种情况下,只要你想要,就可以returnbreak

这里有很多答案。 这是旧的,但这是通过谷歌来到这里的任何人。 在jQuery中的每个函数

return false; 就像break一样。

只是

return; 就像continue

这些将模仿中断和继续的行为。

正如jQuery文档http://api.jquery.com/jQuery.each/中所述,; return true; 是一样的continue; 在循环中并return false; 就像break;

有没有干净的方法来做到这一点,就像上面提到的@Nick可能会更容易使用老式的循环方式,然后你可以控制这一点。 但是,如果你想坚持你得到的是有一种方法可以处理这个问题。 我相信我会为这个获得一些热量。 但…

没有if语句就可以做你想要的一种方法是引发一个错误,并用try / catch块封装你的循环:

 try{ $(sentences).each(function() { var s = this; alert(s); $(words).each(function(i) { if (s.indexOf(this) > -1) { alert('found ' + this); throw "Exit Error"; } }); }); } catch (e) { alert(e) } 

好吧,让颠簸开始。

这里的问题是,虽然你可以从.eachcallback中返回false,但.each函数本身返回jQuery对象。 所以你必须在两个级别都返回false来停止循环的迭代。 此外,由于没有办法知道内部.each是否匹配,我们将不得不使用一个共享variables使用更新的闭包。

每个words内部迭代都指向同一个notFoundvariables,因此我们只需要在find匹配项时更新它,然后返回它。 外部封闭已经有了一个参考,所以它可以在需要的时候break

 $(sentences).each(function() { var s = this; var notFound = true; $(words).each(function() { return (notFound = (s.indexOf(this) == -1)); }); return notFound; }); 

你可以在这里尝试你的例子 。

很不幸的是,不行。 这里的问题是迭代发生在函数内部,所以它们不像正常的循环。 你可以通过返回或抛出一个exception来“破解”出一个函数。 所以是的,使用布尔标志似乎是从外部“循环”中“打破”的唯一合理方式。

我为此使用了“突破”模式:

 $(sentences).each(function() { var breakout; var s = this; alert(s); $(words).each(function(i) { if (s.indexOf(this) > -1) { alert('found ' + this); return breakout = false; } }); return breakout; }); 

这适用于任何嵌套深度。 breakout是一个简单的标志。 除非你把它设置为false否则它将保持undefined状态(正如我在上面所说的return语句中所做的那样)。 你所要做的就是:

  1. 在最外层的closures中声明它: var breakout;
  2. 将它添加到你的return false语句中: return breakout = false
  3. 在外部封闭中返回突破。

不太不雅,对吗? 无论如何,为我工作。

返回true不工作

返回假工作

 found = false; query = "foo"; $('.items').each(function() { if($(this).text() == query) { found = true; return false; } }); 

在API文档中确认http://api.jquery.com/jQuery.each/说:;

通过使callback函数返回false,我们可以在特定的迭代中打破$ .each()循环。 返回非错误与for循环中的continue语句相同; 它会立即跳到下一个迭代。

这是我的例子http://jsfiddle.net/r6jqP/

 (function($){ $('#go').on('click',function(){ var i=0, all=0; $('li').each(function(){ all++; if($('#mytext').val()=='continue')return true; i++; if($('#mytext').val()==$(this).html()){ return false; } }); alert('Iterazione : '+i+' to '+all); }); }(jQuery)); 

标记的rest

 outerloop: $(sentences).each(function() { $(words).each(function(i) { break; /* breaks inner loop */ } $(words).each(function(i) { break outerloop; /* breaks outer loop */ } }