4

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
  • Why do you want less time load? Is it a very consuming operation? The rule for javascript is that if its not lagging, and there arent an excessive amount of errors, its good code. Commented Jun 19, 2010 at 3:50

5 Answers 5

7

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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
His code is correct. You may use any DOM element as context to descend with a getElementsByTagName or getElementsByClassName like that.
@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". E.g. for(var i = 0, n = elements.length; i < n; i++)
yea, all guys answer is right. I think code of every is similar. also this is right code :). thankyou all :)
@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 :)
5

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.

2 Comments

+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.
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).
1

have you tried the obvious solution?

var nodes = $(".test");
for(var i = 0; i < nodes.length; i++)
{
    var node = nodes[i];
}

3 Comments

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.
Variable declarations are "hoisted" to the top, so what it actually looks like is this: var nodes, node; nodes = $('.test'); for (...) { node = nodes[i]; }
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
1

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

1 Comment

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? ;-)
1

Another alternative:

for (var i = 0; i < $('.test').length; i++){
    var element = $('.test').eq(i);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.