views:

69

answers:

2

I have the following javascript function in my extension:

function findPos(obj) {

var curleft = curtop = 0;
if (obj.offsetParent) {
        curleft = obj.offsetLeft
        curtop = obj.offsetTop
        while (obj = obj.offsetParent) {
                curleft += obj.offsetLeft
                curtop += obj.offsetTop
        }
}
return [curleft,curtop];

And my simplified html example is as follows:

 <span id="a"></span>
 <span id="b"></span>
 <span id="c"></span>
 <span id="d"></span>

To each span tag I append a child element

<div id="a2" style="display: block; position: absolute; height: 50px; width: 50px; border: 1px solid #abcdef; z-index: 9999998;"></div>
<div id="b2" style="display: block; position: absolute; height: 50px; width: 50px; border: 1px solid #abcdef; z-index: 9999998;"></div>
<div id="c2" style="display: block; position: absolute; height: 50px; width: 50px; border: 1px solid #abcdef; z-index: 9999998;"></div>
<div id="d2" style="display: block; position: absolute; height: 50px; width: 50px; border: 1px solid #abcdef; z-index: 9999998;"></div>

Now when the page is static (that is, if I manually edit the html to have the div children), findPos returns the right curleft & curtop for both document.getElementById('a') & a2, however if I create the div dynamically from the extension and append it to the span, findPos returns 0,0 on the new element.

Any ideas why?

I add the divs and run the findPos code from the context of a firefox sidebar like so:

var mydiv = document.createElement('div');
mydiv.setAttribute('style', 

'display: block;position: absolute; height: 50 px; width: 50px; border: 1px solid #abcdef z-index: 9999998;'); mydiv.id = 'a2' var myspan = gBrowser.contentDocument.getElementById('a'); myspan.appendChild(mydiv);

where gBrowser is defined as:

// For accessing browser window from sidebar code.
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                   .getInterface(Components.interfaces.nsIWebNavigation)
                   .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
                   .rootTreeItem
                   .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                   .getInterface(Components.interfaces.nsIDOMWindow);
var gBrowser = mainWindow.gBrowser;

I've tried adding the findPos code to the page itself, however same thing.

A: 

Just a guess here, but element.getOffsetParent will return null (as well as getOffsetLeft/Right returning 0 i think) if the element display style is set to "none".

You can check the computed style using:

document.defaultView.getComputedStyle(document.getElementById("a"), "").display
Amitay Dobo
That may be true, however all of the elements I try to find have display: block;Using your code snippet confirms it.
Ivan Kruchkoff
Wrong guess then :) Maybe you could post some code for reproducing the problem: i.e. how the elements are added dynamically, when is the findPos() routine being called.
Amitay Dobo
@Amitay Dobo, I've updated the question to give further information.
Ivan Kruchkoff
Would go with another guess then, since I don't have the firefox extension to test this on... Maybe you could try using gBrowser.contentDocument.createElement('div') instead of document.createElement(). I know that creating an element on a one document and adding it to another can have some strange side effects. However, when I tried something similiar to your code and create the element on an IFRAME (instead on an extension) it did work.
Amitay Dobo
Oops, it's already figured out. Scratch that comment.
Amitay Dobo
A: 

So I found the issue when I was writing up further details, hopefully this helps someone when they're trying to figure out why an element has 0,0 coordinates when appended to the dom from a firefox extension (in a sidebar or toolbar).

The issue lies in this innocuous line of code:

var mydiv = document.createElement('div');

We're creating mydiv in the document of the browser chrome. We can append it to the element within the gBrowser, and it appears visually, however we findpos gives us 0,0.

However if we change it to:

var mydiv = gBrowser.contentDocument.createElement('div');

We get the right values for findpos.

Ivan Kruchkoff
If anyone could point to any document where something of this nature is stated, I'd be very appreciative, in order to prevent the DAYS spent troubleshooting all of the side issues that arose from this bug.
Ivan Kruchkoff
Oops, guessed it in my other comment, but 2 days too late! Glad you have found the solution. Didn't find anything documented about the problem either.
Amitay Dobo
Thank Amitay Dobo for your persistence in trying to help me resolve this, if you hadn't asked me for more info, I would still be scratching my head.
Ivan Kruchkoff