offsetLeft Value Changes Unexpectedly

279 Views Asked by At

Consider the following code segment:

var iframe = document.createElement('iframe');
iframe.src = 'foobar.html';
document.body.appendChild(iframe);

iframe.onload = function () {
    var nodeIterator = iframe.contentDocument.createNodeIterator(
        iframe.contentDocument.body,
        NodeFilter.SHOW_ELEMENT,
        { acceptNode: function (node) {
            if (node.hasAttribute('id')) {
                return NodeFilter.FILTER_ACCEPT;
            } else {
                return NodeFilter.FILTER_SKIP;
            }
        }}, false),
    currentNode, someArray = [];

    while (currentNode = nodeIterator.nextNode()) {
        // Calculate offsetLeft
        someArray.push({
            id: currentNode.id,
            left: (function () {
                var a = currentNode, b = 0;
                while (a) {
                    b += a.offsetLeft;
                    a = a.offsetParent;
                }
                return b;
            }())
        });

        // On element click, log offsetLeft after calculating again
        currentNode.onclick = function (e) {
            e.stopPropagation();
            var a = this, b = 0;
            while (a) {
                b += a.offsetLeft;
                a = a.offsetParent;
            }
            console.log(b);
        };
    }
};

The issue I'm having is this: For some of the elements, the offsetLeft calculation is different the second time it's calculated. Using Google Chrome's inspector, I can see that the second time the calculation occurs offsetLeft is always accurate.

The offsetLeft calculation done during Node Iteration is wrong for some elements, but consistently (the value is always the same across page refreshes).

I'm wondering if anyone has any insights as to why this is the case. I've been thinking that iframe.onload actually fires before the elements in its contentDocument have finished loading completely, causing some elements to be further left or right initially.

0

There are 0 best solutions below