嵌套 jQuery.each() - 继续/中断
Posted
技术标签:
【中文标题】嵌套 jQuery.each() - 继续/中断【英文标题】:Nested jQuery.each() - continue/break 【发布时间】:2011-03-17 02:24:59 【问题描述】:考虑以下代码:
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() 循环。根据the documentation,返回 false 将跳出循环(停止执行循环 - 类似于正常的 javascript break 语句),返回非 false 将停止当前迭代并继续下一次迭代(类似于正常的 JavaScript continue 语句)。
我可以自行中断或继续 jQuery.each(),但使用嵌套的 jQuery.each,我发现很难从子循环中中断父循环。我可以使用布尔值,并在每次子迭代时更新它,但我想知道是否有更简单的方法。
我已经设置了an example at jsFiddle,如果你想弄乱它。只需单击“测试”按钮即可运行上述示例。
TLDR: 在 jQuery 的上下文中是否有类似标记的 continue 或 break 的东西?
【问题讨论】:
看起来你在这里过度使用 jQuery,一个简单的for
循环会做你想做的事:)
这是一个非常简单的例子。实际上,我正在循环使用 jQuery 选择的 DOM 节点等。
【参考方案1】:
您可以通过使回调函数返回 false 来在特定迭代中中断 $.each()
循环。
返回非 false 与 for 循环中的 continue
语句相同;它将立即跳到下一次迭代。
【讨论】:
【参考方案2】:如 jQuery 文档中所述http://api.jquery.com/jQuery.each/
jQuery.each
中的return true
与continue
相同
return false
与break
相同
【讨论】:
$(selector).each() VS $.each(set) - 我希望它的工作原理相同:)【参考方案3】:我为此使用了“突破”模式:
$(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
是一个简单的标志。它将保持undefined
除非并且直到您将其设置为false
(正如我在我的return 语句中所做的那样,如上图所示)。您所要做的就是:
-
在你最外层的封盖中声明它:
var breakout;
将其添加到您的 return false
声明中:return breakout = false
在您的外部封盖中返回突破。
不会太不雅吧? ...反正对我有用。
【讨论】:
这真的很好,遗憾的是所有其他答案 - 除了所选答案之外都是错误的。【参考方案4】:在 API 文档中确认 http://api.jquery.com/jQuery.each/ 说:
我们可以在特定的迭代中打破 $.each() 循环,方法是 回调函数返回假。返回非 false 与 a 相同 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));
【讨论】:
【参考方案5】:这里有很多答案。它很旧,但这适用于通过谷歌来到这里的任何人。在jQuery中每个函数
return false;
类似于break
。
只是
return;
就像continue
这些将模拟中断和继续的行为。
【讨论】:
请参阅 Serj 的回答。它被否决了,因为你不能有一个标记return true
或return false
实际上我尝试在 Firefox 中返回 true,这对我来说与 break 相同。这就是我回答的原因。
这不会脱离嵌套循环。【参考方案6】:
标记中断
outerloop:
$(sentences).each(function()
$(words).each(function(i)
break; /* breaks inner loop */
$(words).each(function(i)
break outerloop; /* breaks outer loop */
【讨论】:
真的有用吗?标记突破功能边界?【参考方案7】:return true不起作用
返回 false 工作
found = false;
query = "foo";
$('.items').each(function()
if($(this).text() == query)
found = true;
return false;
);
【讨论】:
【参考方案8】:这里的问题是,虽然您可以从 .each
回调中返回 false,但 .each
函数本身会返回 jQuery 对象。因此,您必须在两个级别都返回 false 以停止循环的迭代。此外,由于无法知道内部 .each
是否找到匹配项,我们将不得不使用一个共享变量,并使用一个更新的闭包。
words
的每个内部迭代都引用同一个notFound
变量,所以我们只需要在找到匹配时更新它,然后返回它。外部闭包已经有对它的引用,所以它可以在需要时break
out。
$(sentences).each(function()
var s = this;
var notFound = true;
$(words).each(function()
return (notFound = (s.indexOf(this) == -1));
);
return notFound;
);
你可以试试你的example here。
【讨论】:
【参考方案9】:没有干净的方法可以做到这一点,就像上面提到的@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)
好的,让我们开始吧。
【讨论】:
哇。这可能是对 try/catch 的公然误用,但它确实有效。 @Ryan 是的,我知道。它完全违背了我们被教导做什么/如何做事。但我只是想提出一个解决方案。 很高兴能提供帮助。惊讶并没有真正的颠簸。今天一定很轻松,否则我承认不是最佳实践方法。 差点给你检查了这个,但感觉太脏了:-D 说真的,聪明的解决方案。 我也喜欢!这正是我们现在将其称为“抛出异常”而不是“引发错误”的原因。只需将“退出错误”更改为更外交的“遇到退出条件”之类的,我们已经洗白了这个概念并使其在政治上正确。 :) 有人可能会说(如果有人进行自旋篡改)这里的规则是当遇到退出条件时循环“例外”,此时会引发异常。【参考方案10】:很遗憾,没有。这里的问题是迭代发生在函数内部,所以它们不像正常循环。您可以“打破”函数的唯一方法是返回或抛出异常。所以是的,使用布尔标志似乎是“打破”外部“循环”的唯一合理方法。
【讨论】:
【参考方案11】:你应该这样做没有 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;
You can try it out here。我不确定这是否是您所追求的 exact 行为,但现在您不在由双 .each()
创建的闭包内的闭包中,您可以 return
或 @ 987654326@ 在这种情况下随时可用。
【讨论】:
非常好。即使使用构成我实际用例的更复杂的 jQuery DOM 选择器,它们也可以正常迭代。 普通 JavaScript 得到检查。伙计,我喜欢这种语言。 这个解决方案是无可挑剔的正确,但它没有解决所述问题。它没有解释如何打破嵌套的“每个”循环链。因此-1(对不起) @Legna 是的......尼克说你可以使用这个解决方案返回(从两个循环中中断)或中断(从内部循环中中断)。以上是关于嵌套 jQuery.each() - 继续/中断的主要内容,如果未能解决你的问题,请参考以下文章