Emre Ekmel
Emre Ekmel

Reputation: 23

fastest way to find element position using javascript?

I've used jquery's offset().top, but when running it 4000 times in a loop the browsers freezes for a few seconds. Is there a faster way to get this?

This is happening on the iPAD the desktop is faster.

for (counter=1; counter<4000; counter++)
{
   yPos = Math.round($("#star_"+counter).offset().top);

Upvotes: 0

Views: 2180

Answers (3)

Ed Bayiates
Ed Bayiates

Reputation: 11230

Instead of this:

for (counter=1; counter<4000; counter++) {
    yPos = Math.round($("#star_"+counter).offset().top);
    // etc
}

Assign a class to all stars (let's call it class="starry") and do this:

var cacheStars = $(".starry");

This never needs updating unless you add or remove stars, in which case you can refresh it. Then your loop becomes:

cacheStars.each(function(index, element) {
    ypos = element.offsetTop;
});

Upvotes: 0

Blazemonger
Blazemonger

Reputation: 92953

.offset().top always returns an integer, so rounding it is unnecessary. Furthermore, you can cache the jQuery object for efficiency:

$box = $('#box');
// start your loop here
    yPos = $box.offset().top;
// end loop

UPDATE

Assign a class to each star so you don't have to keep creating new jQuery objects:

$('.stars').each(function(i,el) { 
    var yPos = this.offsetTop; 
});

http://api.jquery.com/each

https://developer.mozilla.org/en-US/docs/DOM/element.scrollTop

Upvotes: 1

You could also not use jQuery...

var element = document.getElementById("box");
var top = element.offsetTop;
while (element.parentNode) {

    element = element.parentNode;
    top += element.offsetTop;

}
console.log(top);

jQuery does a bit of extra work getting the div, than pure javascript. So if speed is an issue here, you should use pure javascript.

But if these are stars in a sky you could just use offsetTop and be sure that they are contained in a div that fills the whole screen:

document.getElementById("box").offsetTop;

But I also guess that you do some kind of calculation to put the stars there in the first place. You should create an Array of the stars, referencing the divs. Something like:

var stars = [];

for (var x = 0; x < 4000; x++) {

    var star = document.createElement("DIV");
    var position = setStarPosition(star);
    stars.push({

        star: star,
        position: position

    });
    document.body.appendChild(star);

}

function setStarPosition(star) {

    // Some positioning code which stores left and top position in variables

    return {

        left: left,
        top: top

    }

}

When you want to manipulate the stars you go through the array, which has the position and a reference to the div.

Referencing divs inside the javascript environment (f.ex. in an array) is A LOT faster than referencing them in the DOM.

Upvotes: 0

Related Questions