views:

97

answers:

4

hi everybody!

Today i'm very stack with a Work and jQ. I was get a morning for it but i can't resolve it :(. My Work here:

<div class="container">
    <p class="test">a</p>
    <div>
        <p class="test">a</p>
    </div>
</div>

In normal, i can using jQ with each function for select all <p class="test">a</p> EX:

$(".test").each(function() {
    $(this).text('a');
});

But i hear everyone talk that, for function get a less timeload than each function. Now i want using for instead of each.. but i don't know how to write code jQ in this case.

Somebody can help me!. thankyou!

+1  A: 

have you tried the obvious solution?

var nodes = $(".test");
for(var i = 0; i < nodes.length; i++)
{
    var node = nodes[i];
}
Sergej Andrejev
The for block is not a closure, so you would be technically redefining the same variable on each loop. Not sure, but I think that throws an error.
Doug Neiner
Variable declarations are "hoisted" to the top, so what it actually looks like is this: `var nodes, node; nodes = $('.test'); for (...) { node = nodes[i]; }`
Casey Hope
why would I reference same element. nodes is a array of html elements. i-th element in this collection is one of found elements with class test. I don't see a problem here
Sergej Andrejev
+6  A: 

I wouldn't worry about it unless you were iterating through hundreds of them.

for loop is usually used with normal DOM (aka without jQuery) traversing, like...

var elements = document.getElementById('something').getElementsByTagName('a');

var elementsLength = elements.length;

for (var i = 0; i < elementsLength; i++) {

    elements[i].style.color = 'red';
}

Caching of elementsLength is a good idea so it is not calculated every iteration. Thanks to CMS for this suggestion in the comments.

Just adapt that for your jQuery object if you wanted to do it with jQuery.

Replace elements variable with your jQuery collection, like $('#something a'). I think you may need to rewrap the object if you need to do any more jQuery stuff with it.

alex
last time I checked getElementById returned one html element, which hadn't had any methods like getElementsByTagName. That is only what document had. Long story short I don't think it's possible to chain methods like that with native javascript methods
Sergej Andrejev
His code is correct. You may use any DOM element as context to descend with a getElementsByTagName or getElementsByClassName like that.
Dave Ward
@alex: The condition of your loop should be `i < elements.length` since `elements[elements.length]` will be `undefined` (they are 0-based) otherwise you'll get a `TypeError` at the last iteration, also when working with HTMLCollections is a good idea to *cache* the value of `length` property, because accessing that value on each iteration is expensive, since HTMLCollections are ["live"](http://www.w3.org/TR/DOM-Level-2-HTML/glossary.html#dt-live). E.g. `for(var i = 0, n = elements.length; i < n; i++)`
CMS
yea, all guys answer is right. I think code of every is similar. also this is right code :). thankyou all :)
Rueta
@CMS I knew cacheing the length was a good idea, but wasn't sure if adding it would cloud the most important thing - the actual traversal. Still, I included it :)
alex
cache length is a good idea. this help performance better.
Rueta
+3  A: 

One thing to watch out for is that using an ordinal accessor on the result of a jQuery selection will return a native DomElement. If you want to use jQuery methods on them, you have to re-wrap them:

var testElements = $('.test');

for (var i = 0; i < testElements.length; i++) {
  // Using $() to re-wrap the element.
  $(testElements[i]).text('a');
}

I'd second what others have said though. Unless you're dealing with many elements, this is premature optimization. Re-wrapping the elements to use the .text() method may even bring it back to no gain at all.

Dave Ward
oh thankyou!. that is way i want!.
Rueta
+1 for "Re-wrapping the elements to use the .text() method may even bring it back to no gain at all.". I don't have any benchmarks, but it sounds cumbersome to rewrap every iteration.
alex
i don't understand this re-wrap case... can you explain this more detail . pls..
Rueta
Re-wrapping is the `$(element)` step within the loop. That's necessary if you still want to be able to use jQuery's methods on each element, but it comes at a performance cost for each iteration (as jQuery much construct a new jQuery object to wrap that element with its extended functionality).
Dave Ward
oh i understand this now!. thanks so much!
Rueta
+1  A: 

This article shows that each() has no significant performance penalty until you get into the hundreds of thousands of looped-over items.

Brock Adams
yea.. but i want optimazing my code..
Rueta
That's commendable, but this would be a trivial performance gain at the cost of decreased code clarity and maintainability. I'd bet there are bigger performance hogs elsewhere. Like `Something.length` in a `for` loop maybe? ;-)
Brock Adams