5

I'm trying to write a Firefox extension that adds elements to the loaded page. So far, I get the root element of the document via

var domBody = content.document.getElementsByTagName("BODY").item(0);

and create the new elements via

var newDiv = content.document.createElement("div");

and everything worked quite well, actually. But the problems came when I added a button with on onclick attribute. While the button is correctly displayed, I get an error. I already asked asked here, and the answer with document.createElement() (without content) works.

But if I remove the 'content.' everywhere, the real trouble starts. Firstly, domBody is null/undefined, no matter how I try to access it, e.g. document.body (And actually I add all elements _after_the document is fully loaded. At least I think so). And secondly, all other elements look differently. It's seem the style information, e.g., element.style.width="300px" are no longer considered.

In short, with 'content.document' everything looks good, but the button.onclick throws an error. with only 'document' the button works, but the elements are no longer correctly displayed. Does anybody see a solution for that.

Community
  • 1
  • 1
Christian
  • 3,239
  • 5
  • 38
  • 79

2 Answers2

4

It should work fine if you use addEventListener [MDN] (at least this is what I used). I read somewhere (I will search for it) that you cannot attach event listener via properties when creating elements in chrome code.

You still should use content.document.createElement though:

 Page = function(...) {
   ...
 };

 Page.prototype = {
   ...
   addButton : function() {
     var b = content.document.createElement('button');
     b.addEventListener('click', function() { 
         alert('OnClick'); 
     }, false);
   },
   ...
 };

I would store a reference to content.document somewhere btw.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Awesome, it works! Thanks a lot for that! --- I noticed when I click the button - of course the alert appears - the page reloads. Why is that so and how can I avoid that? – Christian Aug 15 '11 at 17:19
  • 1
    @Christian: Good question. I'm not sure. A `button` is by default a form submit button, but you have no form. Nevertheless, try to set the value of the `type` attribute to `button`: http://www.w3.org/TR/html4/interact/forms.html#h-17.5 – Felix Kling Aug 15 '11 at 17:27
  • Felix, you saved my day...at least you saved me a lot of time :). Many thanks again to you and all the others! – Christian Aug 15 '11 at 17:45
  • @Christian: So setting the `type` worked? In any case, you're welcome and happy coding! :) – Felix Kling Aug 15 '11 at 18:07
  • Yes, `button.type="button"` did it! Thanks, again! – Christian Aug 16 '11 at 06:21
3

The existing answer doesn't have a real explanation and there are too many comments already, so I'll add another answer. When you access the content document then you are not accessing it directly - for security reasons you access it through a wrapper that exposes only actual DOM methods/properties and hides anything that the page's JavaScript might have added. This has the side-effect that properties like onclick won't work (this is actually the first point in the list of limitations of XPCNativeWrapper). You should use addEventListener instead. This has the additional advantage that more than one event listener can coexist, e.g. the web page won't remove your event listener by setting onclick itself.

Side-note: your script executes in the browser window, so document is the XUL document containing the browser's user interface. There is no <body> element because XUL documents don't have one. And adding a button won't affect the page in the selected tab, only mess up the browser's user interface. The global variable content refers to the window object of the currently selected tab so that's your entry point if you want to work with it.

Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
  • Thanks, Wladimir, for explaining! I only found bits and pieces referring to the various differences. I always like _why_ my solution does actually work, or why not :). – Christian Aug 16 '11 at 12:25