Событие DOMContentLoaded дважды срабатывает для загрузки одной страницы
Я написал дополнение 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);
эту проблему легко исправить, вставив уникальный элемент DOM, а затем проверив его существование в начале. Мой вопрос заключается в том, должны ли разработчики надстроек ожидать этого поведения событий как обычно или эта проблема в первую очередь является ошибкой/побочным эффектом в надстройке AVG?
2 ответов
Я не знаю, буду ли я считать это "нормальным", однако возможности внешних приложений влиять на работу вашего плагина бесконечны.
тем не менее, я думаю, что независимо от AVG, вызывающего эту аномалию, умная вещь, как вы сказали, - проверить, существует ли столбец до вставки, поскольку AVG может быть не единственным внешним приложением, которое влияет на триггеры событий firefox.
Я очень устал от событий, управляемых DOM, потому что в моем собственном плагине, и тестирование его на протяжении всей разработки показало множество аномалий, основанных на стольких переменных (разные ОС, разные версии FF, разные приложения на хост-компьютере, разные плагины в рамках любого данного пользователя FF и т. д..)
подведем итоги:
- ошибка в AVG? может быть.
- существует ли потенциал для вашей производительности плагина, который будет зависеть от многих других источников? абсолютно!
- решение: IMHO-всегда проверяйте, были ли внесены изменения до внесения фактического изменения для всех элементов DOM просто для безопасности.
попробуйте прочитать метод bindReady jquery:
https://github.com/jquery/jquery/blob/master/src/core.js
вас ждет:
if ( readyBound ) {
return;
}
readyBound = true;
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", jQuery.ready, false );