Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DOMContentLoaded event firing twice for a single page load

I authored a Firefox add-on several months ago that recently failed. The add-on basically looks for a particular URL and then modifies the DOM for the page. I traced the failure to the (accidental) installation of the "AVG Safe Search" add-on. I found that, with the AVG add-on disabled, the DOMContentLoaded event fires once for the document (behavior I originally expected), but with it enabled, the DOMContentLoaded event fires twice for the document. My add-on inserts a column into an HTML table, so because the event fires twice, two duplicate columns are inserted rather than one.

Here's the distilled initialization code of my add-on:

var hLoadListener = function(event) { myAddon.initialize(event); }
var hContentLoadedListener = function(event) { myAddon.onContentLoaded(event); }

myAddon.initialize = function(aEvent)
{
    gBrowser.addEventListener("DOMContentLoaded", hContentLoadedListener, false);
};

myAddon.onContentLoaded = function(aEvent)
{
    if (!(aEvent.originalTarget.nodeName === "#document")) { return; }

    var doc = aEvent.target; // document that triggered "onload" event

    if (!(doc instanceof HTMLDocument)) { return; }
    if (!doc.location) { return; }

    var href = doc.location.href; // URL of current page

    if (URLRegExp.test(href))
    {
      // Modify the page's DOM
    }
};

window.addEventListener("load", hLoadListener, false);

This issue seems easy to fix by inserting a unique DOM element and then testing for it's existence at the start. My question is whether add-on developers should expect this event behavior as normal or whether this issue is primarily a bug/side-effect in the AVG add-on?

like image 920
Jeremy Giron Avatar asked Dec 04 '10 19:12

Jeremy Giron


People also ask

What triggers DOMContentLoaded?

The DOMContentLoaded event fires when the HTML document has been completely parsed, and all deferred scripts ( <script defer src="…"> and <script type="module"> ) have downloaded and executed. It doesn't wait for other things like images, subframes, and async scripts to finish loading.

What is the difference between DOMContentLoaded and load?

The load event is fired when the whole page has loaded, including all dependent resources such as stylesheets and images. This is in contrast to DOMContentLoaded , which is fired as soon as the page DOM has been loaded, without waiting for resources to finish loading.

What is document Addeventlistener (' DOMContentLoaded?

The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. A different event, load , should be used only to detect a fully-loaded page.


2 Answers

I don't know if I would consider this "normal" however the possibilities for outside applications to affect the operation of your plugin are endless.

That said, I think regardless of AVG causing this anomoly, the smart thing to do, like you said, is to check if the column exists prior to insertion, as AVG may not be the only outside application that influences firefox event triggers.

I am very weary of the DOM driven events because in my own plugin, and the testing of it throughout development has shown PLENTY of anomolies based on so many variables (different OS, different version of FF, different applications on host computer, different plugins within any given users FF, etc..)

To summarize:

  • Bug in AVG? Maybe.
  • Is the potential there for your plugin performance to be affected by MANY other sources? Absolutely!
  • Solution: IMHO- Always check to see if your change has been made prior to making the actual change for all DOM items just to be safe.
like image 130
Purge Avatar answered Oct 12 '22 08:10

Purge


document.addEventListener('DOMContentLoaded', () => {
    console.log('DOMContentLoaded');
    // do stuff
},{ once: true });
like image 5
Lee Probert Avatar answered Oct 12 '22 08:10

Lee Probert