вторник, сентября 18, 2007

установка обработчиков событий в javascript

Я уже говорил, что люблю яваскрипт? Если нет, то: "лучше языка я ещё не встречал!". Есть, конечно и недостатки, но многие из них можно обойти...
Но сейчас пойдёт речь не о недостатках, а наоборот, об одном элегантном решении...

Самый простой способ повесить обработчик события - это просто написать:
node.onclick= function( e ){
if( !e ) e= window.event;
alert( e );
}

Метод довольно простой и наглядный, но основной его недостаток - для одного события у одного узла можно назначить только один обработчик, что очень неудобно.

Более сложный способ, лишённый этого недостатка, - это воспользоваться методами addEventListener (DOM) и attachEvent (IE). Например: http://php.ru/forum/viewtopic.php?t=7374

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

И тут мы подходим к самому главному! В яваскрипте любая функция является объектом, а значит она может иметь дополнительные свойства. В частности, можно задать каким-нибудь свойством массив обработчиков, а функция должна просто пройтись по каждому из них и запустить. В итоге у меня получился такой код:
node.observe= function( event, func ){
if( !node[event] ){
node[event]= function f( e ){
if( !e ) e= window.event;
var funcs= node[event].funcs;
for( var i= 0; i < funcs.length; ++i ){
if( funcs[i] ) funcs[i]( e );
});
};
node[event].funcs= [];
}
var funcs= node[event].funcs;
for( var i in funcs )
if( funcs[i] == func ) return;
funcs.push( func );
}
node.unobserve= function( event, func ){
var funcs= node[event].funcs;
for( var i in funcs )
if( funcs[i] == func )
delete funcs[i];
}

то есть, мы расширяем html-ноду ( хотя, в ИЕ наврятли удастся расширить что-то отличное от html-елемента -_- ну да не суть ) двумя функциями, одна из которых добавляет обработчик, а вторая - удаляет.

Примеры использования:
function ping( e ){
alert( e );
}

node.observe( 'onclick', ping );

node.unobserve( 'onclick', ping );

node.observe( 'onmyevent', ping );

node.onmyevent( { keyCode: 1 } );


upd: кстати, на событие 'onbeforeunload' и возможно на ещё какие-то нельзя вешать обработчики с помощью addEventListener/attachEvent, ибо некроссбраузерно.

upd2: мля... не работает в мозилле в designMode... придётся оной подпорки делать...

3 комментария:

Анонимный комментирует...

на 8-й строке парс еррор. ")" лишняя?

Анонимный комментирует...

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

Анонимный комментирует...

Pompano Beach FL locksmith
Locksmith Walnut Creek CA