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 документа.
То есть Вам надо писать Ваш код просто в глобальном контексте расширения и не усложнять себе жизнь какими-то таймаутами, обработчиками и тд.

heckfy 04.10.2010 05:55

Цитата:

Сообщение от Alex82 (Сообщение 38036)
Т.е. моя функция вызывается но не завершается

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

heckfy 04.10.2010 06:02

Цитата:

Сообщение от Alex82 (Сообщение 38038)
Про дзен тут написано http://archive.flashnewz.com/flashne...entInIE.h tml

вы расширение к чему пишете? судя с ваших слов к хрому, тогда не совсем понятно причем тут осёл и костыли для его багов.
мне кажется код расширения хрома выполняется после скриптов страницы. в любом случае это очень легко проверить.

:-?

sotik 22.02.2013 08:14

В плагине такой скрипт:
function pipa()
{
alert("Скрипт работает");
}
    var wos = document.getElementById("bamForm");
    wos.innerHTML = "<a href='#' onClick='pipa()'>testik</a>";
На страничке есть контейнер:
<p id="bamForm"></p>
Скрипт работает как положено,то есть выводит в dom ссылочку.
Нажимаю на ссылочку и обработчик не запускает функцию.В чем дело?

рони 22.02.2013 10:42

:write:
<!DOCTYPE HTML>
<html>
<head>
  <title></title>
<meta charset="utf-8" />
</head>
<body> <p id="bamForm"></p>
<script type="text/javascript">
function pipa() {
    alert("Скрипт работает");
}
var wos = document.getElementById("bamForm");
wos.innerHTML = "<a href='#' onClick='pipa()'>testik</a>";
</script>
</body>
</html>

sotik 22.02.2013 19:20

Если честно,то я не увидел ответ на свой вопрос, а просо переписаный код в оформленном html.
Поставлю вопрос поконкретней.
Дело в том что если в контейнер вставляется инфа путем работы скрипта в плагине,то эта инфа отображается в lom, но оработчик у нее слетает,если таковой имелся.
как сдеалать,чтоб не слетал

danik.js 22.02.2013 19:31

sotik,

cyber 22.02.2013 21:06

danik.js, а почему так мало стрелочек? плохо видно=(


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