2010-08-12 5 views
8

Я разрабатываю расширение Firefox и имеют следующий код:.onload вызывается несколько раз с расширением Firefox

function initialize() { 
    // For accessing browser window from sidebar code. 
    var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 
       .getInterface(Components.interfaces.nsIWebNavigation) 
       .QueryInterface(Components.interfaces.nsIDocShellTreeItem) 
       .rootTreeItem 
       .QueryInterface(Components.interfaces.nsIInterfaceRequestor) 
       .getInterface(Components.interfaces.nsIDOMWindow); 
    var gBrowser = mainWindow.gBrowser; 
    gBrowser.onload = function() { 
     alert('loaded'); 
    }; 
} 
  1. Когда я открываю расширение (боковая панель) и продолжить, чтобы открыть новую вкладку в в окне Firefox есть три окна.
  2. Когда я обновляю страницу, есть два оповещения.
  3. Когда страница заканчивает загрузку, появляется только одно поле оповещения.
  4. Когда я меняю вкладки, выдается предупреждение.

Я использую .onload, а не DOMContentLoaded или readystatechange, так как мне нужно подождать, пока все остальные javascript не закончит загрузку на странице, прежде чем я запустит мой.

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

РЕШЕНИЕ

Исходя из предположения MatrixFrog, вот это решение, я пришел:

function initialize() { 
    // For accessing browser window from sidebar code. 
    var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 
       .getInterface(Components.interfaces.nsIWebNavigation) 
       .QueryInterface(Components.interfaces.nsIDocShellTreeItem) 
       .rootTreeItem 
       .QueryInterface(Components.interfaces.nsIInterfaceRequestor) 
       .getInterface(Components.interfaces.nsIDOMWindow); 
    var gBrowser = mainWindow.gBrowser; 
    if (gBrowser.addEventListener) { 
     gBrowser.addEventListener("load",pageLoaded,true); 
    }  
} 

function pageLoaded(aEvent) { 
    if ((aEvent.originalTarget.nodeName == '#document') && 
     (aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec)) 
    { 
     alert('loaded'); 
    } 
} 
  1. aEvent.originalTarget.nodeName == '#document' проверяет, что страница загружается а не знаками.
  2. (aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec)) проверяет, что элемент, который уволил событие страница на вкладке, а не один из его ссылок IFRAME
  3. gBrowser.onload бы только огонь для xul-image, а не для #document, поэтому он был заменен на gBrowser.addEventListener («load», pageLoaded, true); !
  4. Если вы хотите, чтобы избежать стрельбы событие для новых пустых вкладок, убедитесь, что gBrowser.currentURI.spec = "о: пустой"
+1

Предлагаемое решение не может обрабатывать, когда страницы загружаются на разных вкладках firefox beacause только для одной вкладки (сфокусированная вкладка) условие aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec будет оцениваться как истинный –

ответ

6

От https://developer.mozilla.org/en/Code_snippets/On_page_load

Текущий Firefox trunk nightlies будут запускать функцию onPageLoad для не только документов, но и xul:image s (favicons in tabbrowser). Если вы хотите, чтобы обрабатывать документы, обеспечить aEvent.originalTarget.nodeName == "#document"

Если вы по-прежнему видеть посторонние события «нагрузки» стрельбы, вы можете проверить цель событий, чтобы выяснить, что загружается, и использование аналогичную логику, чтобы избежать вызова логики вашего расширения в определенных конкретных случаях.

+0

Это стреляет намного меньше, но все же делает несколько раз на некоторых страницах. Я предполагаю, что это связано с тем, что iframe запускает событие onload? Просто изучите, как рассказать о загрузке iframe из загрузки документа и о том, есть ли возможность захвата при загрузке страницы и всех ее фреймов. – Ivan

+2

@Ivan, возможно это iframes. Если это не iframe, тогда 'event.originalTarget.defaultView.frameElement' будет null/undefined. – MatrixFrog

+1

@MatrixFrog Есть ли другой способ проверить это? –