The following works as expected:
$(".foo").first().text("hi!")
...because first()
returns a jQuery object.
However, if I want to work with the text()
method for all matches, I need to do:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!")
}
)
...because each()
gives you DOM objects.
What is the design reason behind this baffling difference? How can I avoid having to build a jQuery object for each match?
The $. each() function can be used to iterate over any collection, whether it is an object or an array. In the case of an array, the callback is passed an array index and a corresponding array value each time.
The each() method in jQuery specifies a function that runs for every matched element. It is one of the widely used traversing methods in JQuery. Using this method, we can iterate over the DOM elements of the jQuery object and can execute a function for every matched element.
Answer: Use the jQuery. each() function each() or $. each() can be used to seamlessly iterate over any collection, whether it is an object or an array. However, since the $. each() function internally retrieves and uses the length property of the passed array or object.
A jQuery object is array-like which means that it contains zero or more indexes (properties which names are positive integers starting with zero). Besides those indexes, a jQuery object contains these properties: length. context. selector.
Possibly due to performance reasons related to looping over large collections? If you only need the DOM objects, then you save cycles. If you need the jQuery object, then you can easily get that.
I typically don't provide the 2nd parameter to each, so I can use $(this).
Internally jQuery call this for $("sel").each(function(){});
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
}
And the eq
is a simple slice:
eq: function( i ) {
return i === -1 ?
this.slice( i ) :
this.slice( i, +i + 1 );
}
So you can create a new each
function that instead of object[name]
will do a object:eq(i)
$("*").slice(1,2).toSource() == $("*").eq(1).toSource();
So to create your own each
:
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
callback.call( this.eq(i), i, this.eq(i) )
}
};
$("*").each2(function(i, obj) {
alert(obj); // now obj is a jQuery object
});
It seems that each3
is faster than each2
http://www.jsfiddle.net/m7pKk/2/
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = this.eq(i);
callback.call( jObj, i, jObj )
}
};
$.fn.each3 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = $(this[i]);
callback.call( jObj, i, jObj )
}
};
See this example on jsFiddle with performance measurement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With