1

I recently had received the help of you great people on stackoverflow to help me move a background image the appropriate distance on a mouseover event. This works great, but the problem is that I'm concerned how optimal it is using the each function.

I'm hoping I can get a brief explanation on how to convert this particular code to a for loop as I'm interested in the optimization benefits, but I'm not quite understanding the difference in syntax for how to convert it to a for loop.

var xPosition = -195;
$('div.style-swatches ul li').each(function(){
    $(this).mouseenter(function(){
        $(this).closest('div.chip-style').find('div.chip-preview').css("background-position", (xPosition - ($(this).index() * 195)) + "px 0");
    });
});
8
  • 6
    For someone who doesn't understand enough to make the conversion, you sound terribly sure that converting this to a loop will "optimize" it. Commented Oct 30, 2013 at 22:42
  • You're technically already using a for loop; jQuery is just doing it for you. Commented Oct 30, 2013 at 22:42
  • The performance gain is going to be marginal if any at all since this is essentially what jQuery is doing for you Commented Oct 30, 2013 at 22:43
  • 2
    For the record, what you should do here is just $('div.style-swatches ul li').mouseenter(function() { ... }). There's no need for each at all. Commented Oct 30, 2013 at 22:43
  • Here is jQuery's implementation of $.each for anyone who wants to know. I was curious if they had implemented it using Array.prototype.forEach where possible. Commented Oct 30, 2013 at 22:52

5 Answers 5

4

Simply don't use the .each()

Demo fiddle

$("div.style-swatches li").mouseenter(function() {
     $(this).closest('div.chip-style').find('div.chip-preview').css("background-position", (xPosition - ($(this).index() * 195)) + "px 0");
});
Sign up to request clarification or add additional context in comments.

1 Comment

Nice catch, i keep forgetting that you can assign directly and jQuery loops internally. Also IIRR jQuery uses loop unrolling/unwinding under the cover for speed optimizations
2

Never optimize without benchmarks. First profile your code, collect real data, see what function call really takes up a lot of time/memory and then optimize the discovered performance bottlenecks.

In your particular case, I'd expect the DOM queries to take a few orders of magnitude more time than the loop construct. You could think about simplifying your CSS queries (e.g. changing div.style-swatches ul li to .style-swatches li if appropriate), use the native DOM instead of wrapping everything in a jQuery object,...

As some other answers already pointed out, you don't actually need the loop at all, as .mouseenter() already does that (and uses a .each() loop internally).

1 Comment

This is great advice. Thank you for sharing it and expanding on simplifying the CSS query. Much appreciated.
1

Any selection uses a for loop under the covers. Basically, any time you see $(".css-selector") think, "For all matching elements". In your code the .each(...) just makes the process more explicit.

If you really wanted to break this out into a for loop, you could use your selector and then index the elements directly, a la:

var elems = $('div.style-swatches ul li');
for (var i = 0; i < elems.length; ++i){
  $(elems[i]).mouseenter(function(){
        $(this).closest('div.chip-style').find('div.chip-preview').css("background-position", (xPosition - ($(this).index() * 195)) + "px 0");
    });

}

But again, since jQuery already does this itself, it's doubtful you'll see any beneficial performance impact.

Comments

0

The jquery selector returns an array. You can just iterate on it

var xPosition = -195;
var elements = $('div.style-swatches ul li');
for(var i = 0; i < elements.length; i++) {
    $(elements[i]).mouseenter(function() {
        $(this).closest('div.chip-style').find('div.chip-preview').css("background-position", (xPosition - ($(this).index() * 195)) + "px 0");
    });
}

Comments

0

$('div.style-swatches ul li') returns and array of items ..just loop it

var xPosition = -195;
var items     = $('div.style-swatches ul li');

for (var i = 0, l = items.length; i < l; i++) {
    $(items[i]).mouseenter(function(){
        $(items[i]).closest('div.chip-style').find('div.chip-preview').css("background-position", (xPosition - ($(items[i]).index() * 195)) + "px 0");
    });
}

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.