Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Не срабатывает обработчик window.onload. (https://javascript.ru/forum/events/6693-ne-srabatyvaet-obrabotchik-window-onload.html)

Alex82 15.12.2009 19:33

Не срабатывает обработчик window.onload.
 
Привет Всем,
я новичок в JavaScript и не могу разобраться с одной проблемой. Подскажите, пожалуйста, в чем может быть дело.

Есть код (плагин для Google Chrome):
if (window.top.onload)
   {
        var existingOnload = null;
        existingOnload = window.top.onload;
        window.top.onload = function (ev) {  // сюда не попадаем...      
             if (existingOnload) { existingOnload(ev); }
             setTimeout( Plugin.init , 1);        
        };
   }
   else
   {
        Plugin.init();
   }


На некоторых страницах (например, http://maps.yahoo.com/) срабатывает ветка if (window.top.onload), но не срабатывает функция
window.top.onload = function (ev) {        
             if (existingOnload) { existingOnload(ev); }
             setTimeout( Plugin.init , 1);        
};


Почему такое может быть? Не инициируется событие onload?

На странице http://maps.yahoo.com/ имеется javascript код:
window.onload=YAHOO.Maps.loaded; ...

но по идее должен выполниться он, а затем мой Plugin.init(); Тем не менее упраление не попадает в мою функцию window.top.onload = function (ev) {...}.

Ветка if (window.top.onload) добавлена в связи с тем, что на некоторых сайтах javascript в window.onload выполняет такой код:
objects = document.getElementsByTagName("object");
	for (var i = 0; i < objects.length; i++)
	{
		objects[i].outerHTML = objects[i].outerHTML;
	}

Моя цель сделать так, чтобы этот код отработал РАНЬШЕ моего вызова Plugin.init.

Заранее благодарен!

Environment:
Windows XP SP3
Google Chrome 4.0.249.30

Gvozd 15.12.2009 19:50

Цитата:

Сообщение от Alex82
не срабатывает функция

может быть событие onload просто уже произошло?
гляньте темутему, чтобы посмотреть как определить состояние загруженности страницы, если оно уже наступило
Цитата:

Сообщение от Alex82
objects[i].outerHTML = objects[i].outerHTML;

объясните мне дзен этих строчек

Alex82 16.12.2009 10:56

Я совсем новичок в JavaScript... я сделал так:
if (window.top.onload) {
     Utils.debug_console_write('case_1 begin');
     var existingOnload = null;
     existingOnload = window.top.onload;
     window.top.onload = function (ev) {   
          Utils.debug_console_write('function (ev) begin');     
          if (existingOnload) { existingOnload(ev); }
          setTimeout( Plugin.init , 1);        
          Utils.debug_console_write('function (ev) end');     
     };
      Utils.debug_console_write('case_1 end');
} else {
   Utils.debug_console_write('case_2 begin');
   Plugin.init();
}

//added your code

var readyBound = false;
var bindReady=function(){
    if ( readyBound ) return;
    readyBound = true;
 
    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            ready();
        }, false );
 
    // If IE event model is used
    } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                ready();
            }
        });
 
        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            if ( isReady ) return;
 
            try {
                // If IE is used, use the trick by Diego Perini
                // [url]http://javascript.nwbox.com/IEContentLoaded/[/url]
                document.documentElement.doScroll("left");
            } catch( error ) {
                setTimeout( arguments.callee, 0 );
                return;
            }
 
            // and execute any waiting functions
            ready();
        })();
    }
 
    // A fallback to window.onload, that will always work
    if (window.addEventListener)
        window.addEventListener('load', ready, false);
    else if (window.attachEvent)
        window.attachEvent('onload', ready);
    else
        window.onload=ready;
}
/////------------------------------------------------
var    isReady=false;
var    readyList= [];
    // Handle when the DOM is ready
var ready=function() {
        // Make sure that the DOM is not already loaded
        if ( !isReady ) {
            // Remember that the DOM is ready
            isReady = true;
 
            // If there are functions bound, to execute
            if ( readyList ) {
                // Execute all of them
                var fn_temp=null
                while(fn_temp=readyList.shift()){
                    fn_temp.call( document);
                }
 
                // Reset the list of functions
                readyList = null;
            }
 
            // Trigger any bound ready events
            //jQuery(document).triggerHandler("ready");//???
        }
    }
/////------------------------------------------------
domReady=function(fn) {
        // Attach the listeners
        bindReady();
 
        // If the DOM is already ready
        if ( isReady )
            // Execute the function immediately
            fn.call(document);
 
        // Otherwise, remember the function for later
        else
            // Add the function to the wait list
            readyList.push( fn );
 
        return this;
    }

domReady(function(){
   alert('OK');
});


Utils.debug_console_write - вспомогательная функция для вывода логов. Chrome плагин подгружает этот скрипт на страничку на которую я захожу. Результаты получились такие:
  1. Захожу на http://maps.yahoo.com/ или google.ru.
    Вижу следующие логи:

    13:37:43] case_1 begin
    [13:37:43] case_1 end

    И нет сообщения 'OK' из функции domReady.

    Т.е. моя функция window.top.onload = function (ev) {...} не вызывается.
    ---
  2. Захожу на http://www.yandex.ru/

    Вижу следующие логи:

    [13:42:23] case_1 begin
    [13:42:23] case_1 end
    [13:42:24] function (ev) begin
    [13:42:24] function (ev) end

    Есть сообщение 'OK' из функции domReady.

    Т.е. вроде все ОК.
    ---
  3. Захожу на http://www.holidaylettings.co.uk/rentals/tremezzo/38067
    Вижу следующие логи:
    [13:44:21] case_1 begin
    [13:44:21] case_1 end
    [13:44:21] function (ev) begin

    Есть сообщение 'OK' из функции domReady.

    Т.е. моя функция вызывается но не завершается.
    ---

Alex82 16.12.2009 11:03

Цитата:

Сообщение от Gvozd (Сообщение 38006)
объясните мне дзен этих строчек

Про дзен тут написано http://archive.flashnewz.com/flashne...entInIE.h tml

Alex82 16.12.2009 19:34

Очень нужен совет!

Gvozd 16.12.2009 20:03

да фиг его знает
если вам ничего не помогло из моих советов, то остальное без попытки отладить самому ваш код под хромом кажется гаданием по кофейной гуще

Alex82 17.12.2009 14:51

А вот с помощью этой функции domReady можно проверить, что все обработчики onload, которые определены на сайте уже отработали? Или она проверяет, что DOM загружен?

maxbarbul 17.12.2009 15:36

А Вы пробовали проверить ?
if (typeof Plugin != 'undefined')
{
    setTimeout( Plugin.init , 1);
}

Поясню свою мысль: если код плагина загружается внутри iframe, то у него область видимости iframe. Соответственно, нужно вызвать его изнутри iframe, а функция, замещающая onload вызывается в контексте window.top - главного окна.
Попробуйте использовать замыкание и apply при установке таймера:
if (window.top.onload)
   {
        var existingOnload = null;
        existingOnload = window.top.onload;
        var self = this;
        window.top.onload = function (ev) {  // сюда не попадаем...      
             if (existingOnload) { existingOnload(ev); }
             setTimeout( 
                 function(){
                     Plugin.init .apply(self, arguments);
                 }, 
                     1
             );        
        };
   }
   else
   {
        Plugin.init();
   }

Alex82 17.12.2009 17:30

Попробовал - не сработало - не попадаю я в обработчик (например, на сайте maps.yahoo.com).

Я вообще не уверен, правильно ли писать "if (window.top.onload)" - ведь я могу зайти на любой сайт, и заранее не известно будут ли там фреймы...

heckfy 04.10.2010 05:51

На будущее мой Вам совет: если задаете вопрос, то приводите в примере кода только тот код, который касается исключительно непосредственно задаваемого вопроса. Так Вы сэкономите массу времени тем, кто читает ваши посты.

Мне кажется ответ на вопрос очень прост. Google Chrome расширения загружаются на страницу уже после того как загружен основной документ и случилось событие onLoad документа.
То есть Вам надо писать Ваш код просто в глобальном контексте расширения и не усложнять себе жизнь какими-то таймаутами, обработчиками и тд.


Часовой пояс GMT +3, время: 20:34.