Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Stop iteration in $.fn.each() when the callback returns false #632

Closed
wants to merge 2 commits into from

3 participants

@mitio

As per the documentation, the iteration in $.fn.each() should stop when the iteration callback returns fasle. This way it will also conform to the jQuery API.

Currently, $.fn.each delegates to Array.prototype.forEach. I didn't find a way to stop the iteration when using forEach, thus I had to look for another solution. I wanted to keep the iteration in native code and found out that Array.prototype.every might do the job.

I didn't expose this in the public interface of Zepto and thus the somewhat odd emptyArray.every.call pattern.

Any notes on the implementation are welcome.

@mitio mitio Stop iteration in $.fn.each() when the callback returns false
As per the documentation, the iteration in $.fn.each() should
stop when the iteration callback returns fasle.

Use Array.prototype.every() to emulate this behaviour while
still keeping the iteration code native.
4d69f67
src/zepto.js
@@ -350,7 +350,10 @@ var Zepto = (function() {
})
},
each: function(callback){
- this.forEach(function(el, idx){ callback.call(el, idx, el) })
+ emptyArray.every.call(this, function(el, idx){
+ if (callback.call(el, idx, el) === false) return false
@staabm
staabm added a note

could be shortened to return !!callback.call(el, idx, el)`

@mitio
mitio added a note

Hehe, that's right... :) However, it has to be callback.call(el, idx, el) !== false, because only a false return value, and not a null or a undefined one, should stop the iteration.

I'll change it.

@staabm
staabm added a note

hm you are right... so you could write it with 3x !

@mitio
mitio added a note

I'm not sure what you mean by "3x !". If it's !!!something, I don't know how this would help. Anyway, I pushed a simpler version, based on your suggestion. Thanks for that!

@staabm
staabm added a note

yep looks much better now.

!! will cast the returned value to a boolean and ! would make sure we have the negation, but I think your solution is easier to read..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@mitio mitio Compact $.fn.each a bit
It's a bit simpler now, as per this suggestion by @staabm:
madrobby#632 (comment)
7aeb12b
@mislav
Collaborator

Good catch, thanks! Pulled

@mislav mislav closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 5, 2012
  1. @mitio

    Stop iteration in $.fn.each() when the callback returns false

    mitio authored
    As per the documentation, the iteration in $.fn.each() should
    stop when the iteration callback returns fasle.
    
    Use Array.prototype.every() to emulate this behaviour while
    still keeping the iteration code native.
  2. @mitio

    Compact $.fn.each a bit

    mitio authored
    It's a bit simpler now, as per this suggestion by @staabm:
    madrobby#632 (comment)
This page is out of date. Refresh to see the latest.
Showing with 13 additions and 1 deletion.
  1. +1 −1  src/zepto.js
  2. +12 −0 test/zepto.html
View
2  src/zepto.js
@@ -350,7 +350,7 @@ var Zepto = (function() {
})
},
each: function(callback){
- this.forEach(function(el, idx){ callback.call(el, idx, el) })
+ emptyArray.every.call(this, function(el, idx){ return callback.call(el, idx, el) !== false })
return this
},
filter: function(selector){
View
12 test/zepto.html
@@ -698,6 +698,18 @@
t.assertEqual(2, index)
},
+ testEachBreak: function(t){
+ var index, tagnames = []
+ $('#eachtest > *').each(function(idx, el){
+ index = idx
+ t.assertIdentical(el, this)
+ tagnames.push(el.tagName.toUpperCase())
+ if (idx == 1) return false
+ })
+ t.assertEqual('SPAN, B', tagnames.join(', '))
+ t.assertEqual(1, index)
+ },
+
testMap: function(t){
var results = $('#eachtest > *').map(function(idx, el) {
t.assertIdentical(el, this)
Something went wrong with that request. Please try again.