расширяя 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(){ … })