Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поздняя инициализация - альтернатива Observer`у 
:(
    Опции темы
Се ля ви
Дата 1.9.2008, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



Часто при создании страниц является проблемой наличие единственного и неповторимого события window.onload (оно же может задаваться в теге "BODY" через св-во "onLoad"), ибо различные сценарии используют его для своей инициализации и им порой бывает трудно договориться о едином механизме включения своих блоков в функцию, служащую обработчиком этого события, что бы все они в итоге корректно были проинициализированы.

Обычно в качестве вспомогательного механизма для разруливания таких конфликтов используется Pattern "Observer". Его суть в том, что заводится специальный реестр, к которому специальным методом осуществляется обращение по добавлению слушателя на событие полной загрузки страницы, который предполагает, что кроме него никто не воспользуется событием window.onload.

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

Так что для таких ситуаций я писал следующий сценарий:
Код
/** @param {function} Init + */
addOnLoadListener = function(Init) {

    var /** @type {function} */ pastInitFn = window.onload;
    if (pastInitFn)
        window.onload = function() { pastInitFn(); Init(); }
    else
        window.onload = Init;
    
};

//Предположим, кто-то "грязно" вмешался и перепрописал механизм инициализации, затерев всё, что, возможно, было там до него. Мы не хотим вмешиваться так же - просто хотим добавить к этой свою функциональность.
window.onload = function(){alert(1);};

//...

(function() {

    function Init() {
        
        alert(2);
        //...
    }
    window.addOnLoadListener(Init);
})();


//...

window.addOnLoadListener(function() {
        
    alert(3);
    //...
});
    
})();

Вот так вот аккуратненько можно решить эту проблему, не трогая существующий код инициализации. Конечно, это не спасёт нас, если кто-то ПОСЛЕ исполнения нашего кода "грязно" перепишет window.onload - но это уже будет виной того, кто это сделает, защититься от этого уже не представляется возможным.


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
solenko
Дата 1.9.2008, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 9
Всего: 67



А разве добавление обработчиков через addEventListener не спасает от всех проблем?


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Се ля ви
Дата 1.9.2008, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



Цитата(solenko @  1.9.2008,  13:04 Найти цитируемый пост)
А разве добавление обработчиков через addEventListener не спасает от всех проблем? 

Вы про этот? Спасал бы, если бы был реализован в IE, но им он не поддерживается.
Впрочем, можно написать библиотечку, которая бы как раз реализовывала на JS нормальную функциональность этого метода в Mozilla`е. Но это довольно большая работа - писать, тестировать...


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
JSman
Дата 1.9.2008, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 279
Регистрация: 10.7.2006

Репутация: нет
Всего: 4



attachEvent
PM ICQ   Вверх
Се ля ви
Дата 1.9.2008, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



Цитата(JSman @  1.9.2008,  15:42 Найти цитируемый пост)
attachEvent 

С ним проблема обратная - он не является частью стандарта и поддерживается только Internet Explorer`ом.

В принципе, можно было бы реализовать эту задачу как переходник - сначала действовать по стандарту, а в случае ошибки - вызывать attachEvent... Можно так smile


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
solenko
Дата 1.9.2008, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 9
Всего: 67



Се ля ви, функция универсального навешивания события написана 100 лет назад и не разу никого не подводила. Если не ошибаюсь, один из вариантов есть в закрепленной теме "все про события". Один из вариантов:
Код

function attachEventListener(target, eventType, functionRef, 
   capture) 
{ 
 if (typeof target.addEventListener != "undefined") 
 { 
   target.addEventListener(eventType, functionRef, capture); 
 } 
 else if (typeof target.attachEvent != "undefined") 
 { 
   target.attachEvent("on" + eventType, functionRef); 
 } 
 else 
 { 
   eventType = "on" + eventType; 

   if (typeof target[eventType] == "function") 
   { 
     var oldListener = target[eventType]; 

     target[eventType] = function() 
     { 
       oldListener(); 

       return functionRef(); 
     }; 
   } 
   else 
   { 
     target[eventType] = functionRef; 
   } 
 } 
}

Здается мне надежней/правильней таки использовать такую функцию чем ваш подход.


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
SelenIT
Дата 1.9.2008, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 49
Всего: 401



В базе знаний XPoint'а раньше тоже висел подобный пример, но пару лет назад третью ветку из него решили выкинуть - браузеров, понимающих JS, но не понимающих ни attachEvent, ни addEventListener, в реальном мире практически не осталось...


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
Се ля ви
Дата 3.9.2008, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



solenko, неплохо, но нельзя ли это как-то присобачить ко всем элементам? Что бы по сути просто сделать заплатку для браузеров, понимающих лишь "attachEvent", что бы заставить их работать по стандарту?
Попытался добавить к Node - оказалось, что в FF это просто кучка констант, а IE вообще такого не знает... :(


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
SelenIT
Дата 3.9.2008, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 49
Всего: 401



К сожалению, в IE, насколько мне известно, элементы не являются "тру-объектами" и расширить их через базовый прототип HTMLElement'а (как в др. браузерах) не получится (хотя обходные решения попадаются, но, как правило, довольно некузявые). А вот сделать наоборот - расширить интерфейс HTMLElement'а в остальных браузерах "мелкомягкими" вариантами методов - достаточно легко (вот первый найденный в гугле вариант).


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
Avb
Дата 5.9.2008, 14:21 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 5.7.2006

Репутация: 4
Всего: 13



Да вы чё, парни!
Люди уже давно пользуются кроссбраузерной реализацией обработчика события domContentLoaded, 
а вы тут обсуждаете onload и навешивание обработчиков!

Хотя справедливости ради скажу, что я не спешу переходить на использование domContentLoaded, т.к. периодически замечаю глюки в ИЕ.
PM MAIL   Вверх
JSman
Дата 7.9.2008, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 279
Регистрация: 10.7.2006

Репутация: нет
Всего: 4



Avb, фишка для IE в scrollLeft. Глюков нет. А отсутствие прототипов для Node в IE, по моему мнению, не является страшным. Аля процедурное программирование в студию smile
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0653 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.