Расширение Chrome, javascript: Почему это срабатывает дважды?

У меня очень простой код в моем (тестовом) расширении Chrome:

    function test()
    {
    alert("In test!");
    }

   chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
    var url = tab.url;
        if (url !== undefined) {

        test();
    }
   });

Мой вопрос: почему test() срабатывает дважды? И что еще более важно, как я могу запустить его только один раз?

Ответ 1

Посмотрите, что представляют собой разные состояния при отправке события. Я полагаю, что он отправляется один раз, когда государство "загружается" или когда государство "завершено". Если это так, то ваша проблема будет исправлена ​​с помощью:

 function test()
    {
    alert("In test!");
    }

   chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
    var url = tab.url;
        if (url !== undefined && changeinfo.status == "complete") {

        test();
    }
   });

Ответ 2

Я тоже был смущен этим и попытался найти ответ. Только после некоторых экспериментов я выяснил, почему я получал несколько "полных" событий обновления для того, что, как я думал, было "обновлением" одной страницы.

Если на вашей странице есть iframes, каждый из них инициирует "полное" событие и пузырится до родительского контента script. Таким образом, более сложные страницы вызовут множество onUpdated событий, если они имеют iframes.

Ответ 3

Когда вы пишете следующий код:

chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
    var url = tab.url;
        if (url !== undefined) {

        test();
    }
});

Вы вызываете addListener и говорите ему, чтобы он вызывал test() не сразу, а скорее всякий раз, когда вкладка обновляется. События обновления вкладки транслируются самим браузером Chrome, что, в свою очередь, приводит к запуску вашего кода test().

Ответ 4

Я знаю, что это старо, но все равно... это происходит со мной тоже, и, возможно, это может помочь кому-то. Заглядывая в объект Tab, который получает функция обработчика, я обнаружил, что свойство favIconUrl отличается в обоих вызовах, поэтому я думаю, что это имеет какое-то отношение к этому, хотя я не имею ни малейшего представления о причине этого.

Я думал, что это ошибка, но после второй мысли и тестирования я отбросил теорию ошибок.

Я знаю, что если два свойства будут изменены, событие запускается дважды с объектом changeInfo, содержащим одно свойство каждый раз. Другими словами, если, например, свойства, которые изменяются, являются статусом и favIconUrl, тогда

changeInfo = {status:"complete"};

а затем в следующем вызове

changeInfo = {favIconuUrl : ".... whatever ..."};

Ответ 5

Я решил эту проблему, проверив заголовок закладки при обновлении:

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {

var title = changeInfo.title;
    if (title !== undefined) {
       doSomething();
    }
});

Ответ 6

Дважды происходит из-за того, что статус загружается один раз и состояние завершается один раз. если вы не уверены в статусе, вы также можете попробовать событие onCreated. Это будет выпущено только один раз!