Comments 36
по-моему, лучше вешать событие тогда уже на document, а не на document.body
подход интересный.. хотя и сомнительный
подход интересный.. хотя и сомнительный
Интересно, а чем подкреплён агрумент "Чем меньше приемников событий прикреплено к документу, тем лучше. Они все загружаются в память и в чрезвычайных случаях могут сильно замедлить работу браузеров." ? И как определить то количество приемников, которое действительно будет тормозить броузер ? (один приемник не тормозит, два не тормозит... А сто приемников ? А десять тысяч приемников ?)
Допустим, что тысяча приемников событий действительно тормозят броузер и возьмём какую-нибудь страницу с функциональностью gmail.com. Тогда последний приведённый код внесёт в код как минимум неразбериху и нечитаемость кода =(
Плюс к тому: представьте себе в функции MMNav.init тысячу разных алгоритмов обработки событий в одном месте. Конструкции типа "если объект такой-то, то делаем это иначе если..." не только не ускорят обработку событий, но и начисто подвесят любой броузер.
Допустим, что тысяча приемников событий действительно тормозят броузер и возьмём какую-нибудь страницу с функциональностью gmail.com. Тогда последний приведённый код внесёт в код как минимум неразбериху и нечитаемость кода =(
Плюс к тому: представьте себе в функции MMNav.init тысячу разных алгоритмов обработки событий в одном месте. Конструкции типа "если объект такой-то, то делаем это иначе если..." не только не ускорят обработку событий, но и начисто подвесят любой броузер.
И как определить то количество приемников, которое действительно будет тормозить броузер ?
опытным путем, имхо
тысячу разных алгоритмов обработки событий в одном месте
предложенное решение не претендует на универсальность. Если у вас обрабатываются событий типа
onmouseover
, onmouseout
, то лучше пользоваться самым первым из предложенных примеров, ибо отслеживать на родительском контейнере все движения мыши нам совсем ни к чемуОпытным путём, конечно всё можно сделать =) Но ведь аргумент про уменьшение приемников является основой всех размышлений. И только в случае когда эффект от уменьшения намного превысит недостатки метода, его стоит повсеместно использовать.
Кстати, а зачем оптимизировать onclick ? Ведь человек мышкой кликает с гораздо меньшей скоростью, чем работает программа =)
Кстати, а зачем оптимизировать onclick ? Ведь человек мышкой кликает с гораздо меньшей скоростью, чем работает программа =)
Вот тест, который сравнивает производительность двух методов.
Event Delegation versus Event Handling.
Думаю, комментарии излишни.
Event Delegation versus Event Handling.
Думаю, комментарии излишни.
Во-первых, события лучше назначать addEventListener || attachEvent.
Во-вторых, предложенные "альтернативные" методы крайне негибкие, они подразумевают одинаковый формат всех ссылок внутри элемента.
И, в-третьих, 60 мс для обработки нужных ссылок чертовски (!) малое время, чтобы его уменьшать.
В последнее время я наблюдаю лёгкое помешательство на "ускорении js".
А в данном случае, "сэкономив" лишние несколько мс, вы ещё и потерятете возможность переопределять уникальные ссылки. Оно вам надо?
Во-вторых, предложенные "альтернативные" методы крайне негибкие, они подразумевают одинаковый формат всех ссылок внутри элемента.
И, в-третьих, 60 мс для обработки нужных ссылок чертовски (!) малое время, чтобы его уменьшать.
В последнее время я наблюдаю лёгкое помешательство на "ускорении js".
А в данном случае, "сэкономив" лишние несколько мс, вы ещё и потерятете возможность переопределять уникальные ссылки. Оно вам надо?
у вас есть данные по скорости работы
addEventListener
|| attachEvent
? помнится мне, что все DOM-методы в IE работают несколько медленноAMD3000+, 10000 а-элементов (~7 страниц одних сплошных коротких ссылок) — onclick:110 ms, attachEvent:170 ms.
Разница в 60 ms не так страшна, как перезаписанное кем-то событие.
Разница в 60 ms не так страшна, как перезаписанное кем-то событие.
Ниже приведены мои данные. IE особенно плохо с этим работает. К тому же, перезапись можно и устранить, добавив простое условие.
Для разработки очень больших проектов, перезапись, наверное, будет актуальна, но для 90–95% разработок это совершенно несущественно, потому что за конкретную реализацию JS-функционала обычно отвечают один–два человека, а они уже могут договориться между собой (хотя в случае даже одного человека это может быть нетривиальной задачей :)
Для разработки очень больших проектов, перезапись, наверное, будет актуальна, но для 90–95% разработок это совершенно несущественно, потому что за конкретную реализацию JS-функционала обычно отвечают один–два человека, а они уже могут договориться между собой (хотя в случае даже одного человека это может быть нетривиальной задачей :)
Количество телодвижений для реализации каждого метода, да и проведенный мной тест показывают, что вам ничто не мешает писать безопасный код. Даже если весь ваш js это пара функций в хидере.
Не знаю, откуда взято 90-95%, но, даже в этом случае, «небольшие проекты» вполне могут подрасти со временем. И к чему вам тогда, спрашивается, этот потенциальный геммор?
Не знаю, откуда взято 90-95%, но, даже в этом случае, «небольшие проекты» вполне могут подрасти со временем. И к чему вам тогда, спрашивается, этот потенциальный геммор?
еще есть Greasemonkey и им подобные, кто захочет прогуляться по вашему приложению и понадобавлять событий)
там, в заключении, исправь пожалуйста
«старых версиях _браузерах_» (на «браузеров»)
«старых версиях _браузерах_» (на «браузеров»)
А если на странице много компонентов, каждый из которых содержит собственные ссылки/кнопки или другие элементы, для которых нужно обрабатывать события? Если каждый будет развешивать свои обработчики на document.body помойка получится.
Имхо каждый сверчок должен знать свой шесток то бишь выше своего контейнера не подниматься.
К тому же, даже при использовании этого общего способа, логично было бы использовать 'attachEvent' (опять же со всеми требуемыми финтами для разных браузеров), а не буквальное определение одного обработчика. Не надо жадничать другим скриптам тоже может оказаться потребен 'window.load'.
Дальше. Функция function getEventTarget(e) в данной интерпретации явно предназначена исключительно для обработки событий, происходящих над ссылками. Причём ссылками, у которых установлен атрибут "href". Я бы предложил либо переименовать её, либо сделать методом 'MMNav', чтобы избежать конфликта имён. Да и просто инкапсулировать частную функциональность в конкретном классе.
Имхо каждый сверчок должен знать свой шесток то бишь выше своего контейнера не подниматься.
К тому же, даже при использовании этого общего способа, логично было бы использовать 'attachEvent' (опять же со всеми требуемыми финтами для разных браузеров), а не буквальное определение одного обработчика. Не надо жадничать другим скриптам тоже может оказаться потребен 'window.load'.
Дальше. Функция function getEventTarget(e) в данной интерпретации явно предназначена исключительно для обработки событий, происходящих над ссылками. Причём ссылками, у которых установлен атрибут "href". Я бы предложил либо переименовать её, либо сделать методом 'MMNav', чтобы избежать конфликта имён. Да и просто инкапсулировать частную функциональность в конкретном классе.
насчет производительности, небольшая модификация описанного в статье кода (последний пример) 10000 раз подключала этот обработчик. Вот результаты (AddEvent / onclick):
IE 5.5 = 800/203
IE 6 = 830/280
IE 7 = 860/270
Firefox 2 = 310/203
Opera 9 = 125/63
Safari 3 = 31 (!)/31 (!)
Вот мой тест:
window.onload = function() // .onload исключительно для эксперимента ;)
{
//
function $time(){ return (new Date()).getTime(); }
//
var amount = 10000, i;
var anch = '';
for(i = 0; i link x';
document.body.innerHTML = anch;
//
var solver = function(){ alert('click') };
var els = document.body.getElementsByTagName('a');
//alert(els.length);
//
var time = $time();
for(i=0; i
window.onload = function() // .onload исключительно для эксперимента ;)
{
//
function $time(){ return (new Date()).getTime(); }
//
var amount = 10000, i;
var anch = '';
for(i = 0; i link x';
document.body.innerHTML = anch;
//
var solver = function(){ alert('click') };
var els = document.body.getElementsByTagName('a');
//alert(els.length);
//
var time = $time();
for(i=0; i
Сорри, вот тест: http://disaen.com/temp/event_test/
Результаты.
FF: onclick 480 / addEventListener 860;
Opera: onclick 500 / addEventListener 550;
IE (а вот тут я ранее вас обманул, всё, оказывается, интереснее): attachEvent 170 / onclick 110 (проверьте, плиз, у себя).
Результаты.
FF: onclick 480 / addEventListener 860;
Opera: onclick 500 / addEventListener 550;
IE (а вот тут я ранее вас обманул, всё, оказывается, интереснее): attachEvent 170 / onclick 110 (проверьте, плиз, у себя).
Ox, конец рабочего дня не вяжется с отсутствием кнопочки "редактировать".
IE: onclick — 170 / attachEvent — 110.
Ещё раз сорри.
IE: onclick — 170 / attachEvent — 110.
Ещё раз сорри.
там тест недостаточно "чистый", потому что сначала генерит код, потом его вставляет (
innerHTML
используется наряду с addEvent
), т.е. я бы сделал статичный HTML, с которым бы и игралсяСогласен. Измененные тесты лежат по тому же адресу.
Результаты, более аккуратно собранные:
FF: onclick — 450 / addEventListener — 500;
Opera: onclick — 170 / addEventListener — 150(!);
IE: onclick — 370 / attachEvent — 110(!).
Проверьте ещё сами, пожалуйста.
Результаты, более аккуратно собранные:
FF: onclick — 450 / addEventListener — 500;
Opera: onclick — 170 / addEventListener — 150(!);
IE: onclick — 370 / attachEvent — 110(!).
Проверьте ещё сами, пожалуйста.
http://exp.lusever.programica.ru/test-ev…
Можете протестировать Вашу версию, немного доработанную. У оперы вообще в среднем:
onclick: 118ms
attachEvent: 81ms
addEventListener: 89ms
Можете протестировать Вашу версию, немного доработанную. У оперы вообще в среднем:
onclick: 118ms
attachEvent: 81ms
addEventListener: 89ms
Вот тест, который сравнивает производительность двух методов.
Event Delegation versus Event Handling.
Думаю, комментарии излишни.
Event Delegation versus Event Handling.
Думаю, комментарии излишни.
Статья довольно интересна, но, имхо, есть более хороший способ.
document.onclick = function() {
var f = arguments.callee, e = arguments[0] || window.event, t = e.target || e.srcElement;
if (f.last && t !== f.last) {
f.last = null;
}
if ((t.nodeName == "a") && (t.className == 'bundle')) {
t.href += '?name=value';
f.last = t;
}
}
Код обрабатывается быстро (если кто-то протестирует и выложит результат - буду весьма благодарен), утечек памяти нет. Правда не знаю о совместимости с Safari...
document.onclick = function() {
var f = arguments.callee, e = arguments[0] || window.event, t = e.target || e.srcElement;
if (f.last && t !== f.last) {
f.last = null;
}
if ((t.nodeName == "a") && (t.className == 'bundle')) {
t.href += '?name=value';
f.last = t;
}
}
Код обрабатывается быстро (если кто-то протестирует и выложит результат - буду весьма благодарен), утечек памяти нет. Правда не знаю о совместимости с Safari...
А что делать с onsubmit?
а чем оно отличается от других событий? просто еще одна "перемычка"-мост появится
Вроде onsubmit на document не срабатывает в ie.
да, в IE проблемы в этом плане, точно. Можно привести пример, когда нам нужно эмулировать onsubmit, и это не достигается другими средствами (например, формированием GET-запроса или "скрытой" отправкой формы)?
Можно смотреть за всплывающими событиями: keyup','mousedown','activate'.
Если обработчик сработает на элементе form или у которой есть предок form, подключаем к этой form нужный нам обработчик. Конечно надо следить чоб на одну и туже форму не навесить несколько обработчиков.
Если обработчик сработает на элементе form или у которой есть предок form, подключаем к этой form нужный нам обработчик. Конечно надо следить чоб на одну и туже форму не навесить несколько обработчиков.
шибко мудро :)
могу выложить код как я это сделал, один раз сделал, несколько раз правил, и везде использую.. куда выложить только? я щас переосмысливаю свои наработки и выкладывать в свой гуглкод не хочется, чтобы не запутать.
В сущности такая байда нужна только для проверки вводимых в форму полей.. вот я и забацал валидатор, ну он еще кое чо может делать во время проверки
В сущности такая байда нужна только для проверки вводимых в форму полей.. вот я и забацал валидатор, ну он еще кое чо может делать во время проверки
Посмотрите еще одно решение по отслеживанию событий на странице.
Вообще свойство "всплывать" у некоторых событий удобно использовать во многих задачах.
Вообще свойство "всплывать" у некоторых событий удобно использовать во многих задачах.
абалдеть html теги не сработали, вообщем ссылка по теме в моем профиле
а можно пояснить, чем это кардинально отличается от проекта Сумина http://jsx.ru/ ? Т.е. идея одна и та же, просто у Вас она проработана меньше, насколько я смог понять
в jsx другая идея, там вся фишка в произвольных событиях на произвольных объектах, а обработку всплывающих обектов я у него не видел, внимательнее чтоли посмотреть.. да он сам на конференции говорил что его движок использует джиквари или бейс2, в этих движках обработчики событий навешиваются на каждый элемент. Если в последнее время ничто не поменялось. У них все шикарно работает до тех пор пока элементы вставлять не начнешь.
После подключения обработчика события на элементы определенной категории вставленные элементы с такой же категорией небудут обработаны, их снова нужно будет подключать.
Насчет проработанности, я еще не дорос до создания супер пупер библиотеки, я только предлагаю компактные решения конкретной проблемы.
После подключения обработчика события на элементы определенной категории вставленные элементы с такой же категорией небудут обработаны, их снова нужно будет подключать.
Насчет проработанности, я еще не дорос до создания супер пупер библиотеки, я только предлагаю компактные решения конкретной проблемы.
jsx я делал для больших, масштабируемых и как целиком, так и по частям reusable (не могу подобрать русский перевод) интерфейсов.
Система событий в jsx никоим образом не влияет на систему событий в DOM она идет паралельно и предназначена для удаления жестких ссылок между объектами и компонентами.
Собственно тут подробно описанно http://jsx.ru/Texts/CustomEvents/index.html.
Как при таком подходе работать с DOM событиями решать разработчику.
Система событий в jsx никоим образом не влияет на систему событий в DOM она идет паралельно и предназначена для удаления жестких ссылок между объектами и компонентами.
Собственно тут подробно описанно http://jsx.ru/Texts/CustomEvents/index.html.
Как при таком подходе работать с DOM событиями решать разработчику.
Sign up to leave a comment.
Практический JS: ускоряем обработку событий