расширяя prototype.js — обработка нескольких событий

prototype.js — моя любимая javascript-библиотека. Но несмотря на то, что в ней есть очень многое, некоторых вещей мне в ней не хватает. Обычно это довольно простая функциональность, которая реализуется в несколько строчек. Впрочем, я понимаю, что creeping featuritis приводит к bloatware, поэтому не предлагаю разработчикам включать весь мой код в ядро. С другой стороны, несколько строчек недостойны включения в скриптеку как отдельный плагин, поэтому я иду стандартным путем, собирая свои маленькие расширения в extend.js. В этом посте и нескольких следующих я буду делиться такими расширениями с миром : )

в prototype есть мощная обертка для назначения обработчиков событиям — Event.observe(). Этот метод обычно вызывается как element.observe('click', function(){ … }). Однако иногда возникает необходимость навесить один и тот же обработчик на несколько событий, например, keypress и click. Естественно, копипастить текст функции не хочется, как не хочется и объявлять ее с именем до назначения. Разумно просто передать вместо одного имени события массив с ними, и это очень просто:

Event.observe = Event.observe.wrap(function(oldFunction, element, eventName, handler){
    $A(Object.isArray(eventName) ? eventName : [eventName]).
        each(function(eventName){ oldFunction(element, eventName, handler); });
    return element;
});

остались только две маленькие детали. Дело в том, что таким образом мы изменили только сам метод Event.observe, но его старая копия осталась в методах элемента и документа. Обновить их — это еще две строчки:

Element.addMethods({ observe: Event.observe });
Object.extend(document, { observe: Element.Methods.observe.methodize() });

вуаля, теперь задача решается просто и изящно: element.observe(['click', 'keypress'], function(){ … })

Артемий Трегубенко,
, ,

comments powered by Disqus