DOMContentLoaded事件针对单个页面加载触发两次

Jer*_*ron 9 javascript dom event-handling firefox-addon

几个月前我创作了一个最近失败的Firefox附加组件.附加组件基本上查找特定的URL,然后修改页面的DOM.我追踪了"AVG Safe Search"插件的(意外)安装失败.我发现,在禁用AVG插件的情况下,DOMContentLoaded事件会为文档触发一次(我最初预期的行为),但启用它后,DOMContentLoaded事件会为文档触发两次.我的加载项将一个列插入到HTML表中,因此事件会触发两次,所以会插入两个重复的列而不是一个.

这是我的附加组件的精简初始化代码:

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);
Run Code Online (Sandbox Code Playgroud)

通过插入一个独特的DOM元素,然后在开始时测试它的存在,这个问题似乎很容易解决.我的问题是附加开发人员是否应该期望此事件行为正常或者此问题主要是AVG插件中的错误/副作用?

Lee*_*ert 7

addEventListener接受一个once参数。MDN 文档说:

一个布尔值,表示监听器添加后最多调用一次。如果为 true,则调用时侦听器将自动删除。如果未指定,则默认为 false。

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#parameters

例子:

document.addEventListener('DOMContentLoaded', () => {
    console.log('DOMContentLoaded');
    // do stuff
}, { once: true });
Run Code Online (Sandbox Code Playgroud)


Pur*_*rge 3

我不知道我是否会认为这是“正常”的,但是外部应用程序影响插件操作的可能性是无限的。

也就是说,我认为无论 AVG 是否导致这种异常,明智的做法是,就像您所说的那样,在插入之前检查该列是否存在,因为 AVG 可能不是影响 Firefox 事件触发器的唯一外部应用程序。

我非常厌倦 DOM 驱动的事件,因为在我自己的插件中,并且在整个开发过程中对其进行的测试显示出基于如此多变量的大量异常(不同的操作系统、不同版本的 FF、主机上的不同应用程序、内部的不同插件)任何给定用户 FF 等..)

总结一下:

  • AVG 中的错误?或许。
  • 您的插件性能是否有可能受到许多其他来源的影响?绝对地!
  • 解决方案:恕我直言,为了安全起见,在对所有 DOM 项进行实际更改之前,请务必检查是否已进行更改。