Пользовательский прослушиватель событий JavaScript
Мне было интересно, может ли кто-нибудь помочь мне понять, как именно создавать разные пользовательские прослушиватели событий.
У меня нет конкретного случая, но я хочу узнать, как это делается, поэтому я могу применить его там, где это необходимо.
То, что я искал, просто нужно, чтобы некоторые люди, возможно, должны были знать, были:
var position = 0;
for(var i = 0; i < 10; i++)
{
position++;
if((position + 1) % 4 == 0)
{
// do some functions
}
}
Ответы
Ответ 1
var evt = document.createEvent("Event");
evt.initEvent("myEvent",true,true);
// custom param
evt.foo = "bar";
//register
document.addEventListener("myEvent",myEventHandler,false);
//invoke
document.dispatchEvent(evt);
Вот как это сделать локально, определяя слушателей и издателей:
http://www.kaizou.org/2010/03/generating-custom-javascript-events/
Ответ 2
Внедрение пользовательских событий не сложно. Вы можете реализовать его разными способами. В последнее время я делаю это так:
/***************************************************************
*
* Observable
*
***************************************************************/
var Observable;
(Observable = function() {
}).prototype = {
listen: function(type, method, scope, context) {
var listeners, handlers;
if (!(listeners = this.listeners)) {
listeners = this.listeners = {};
}
if (!(handlers = listeners[type])){
handlers = listeners[type] = [];
}
scope = (scope ? scope : window);
handlers.push({
method: method,
scope: scope,
context: (context ? context : scope)
});
},
fireEvent: function(type, data, context) {
var listeners, handlers, i, n, handler, scope;
if (!(listeners = this.listeners)) {
return;
}
if (!(handlers = listeners[type])){
return;
}
for (i = 0, n = handlers.length; i < n; i++){
handler = handlers[i];
if (typeof(context)!=="undefined" && context !== handler.context) continue;
if (handler.method.call(
handler.scope, this, type, data
)===false) {
return false;
}
}
return true;
}
};
Объект Observable может быть повторно использован и применен любым конструктором, которым он нужен, просто путем микширования прототипа Observable с protoype этого конструктора.
Чтобы начать прослушивание, вам необходимо зарегистрироваться на наблюдаемый объект, например:
var obs = new Observable();
obs.listen("myEvent", function(observable, eventType, data){
//handle myEvent
});
Или, если ваш слушатель является методом объекта, например:
obs.listen("myEvent", listener.handler, listener);
Где слушатель является экземпляром объекта, который реализует метод "обработчик".
Объект Observable теперь может вызывать свой метод fireEvent всякий раз, когда что-то происходит, когда он хочет общаться со своими слушателями:
this.fireEvent("myEvent", data);
Где данные - это некоторые данные, которые мои слушатели находят интересными. Независимо от того, что вы вкладываете в вас, вы знаете, что лучше всего подходит для вашего пользовательского мероприятия.
Метод fireEvent просто проходит через всех слушателей, которые были зарегистрированы для "myEvent", и вызывает зарегистрированную функцию. Если функция возвращает false, то это означает, что событие отменяется, а наблюдаемый не будет вызывать других слушателей. В результате весь метод fireEvent вернет fasle, чтобы наблюдаемый знал, что любое действие, которое оно уведомляло своих слушателей, теперь должно быть отброшено назад.
Возможно, это решение не подходит всем, но я очень сильно выиграл от этой относительно простой части кода.
Ответ 3
Отсюда:
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
// create the event
var evt = document.createEvent('Event');
// define that the event name is `build`
evt.initEvent('build', true, true);
// elem is any element
elem.dispatchEvent(evt);
// later on.. binding to that event
// we'll bind to the document for the event delegation style.
document.addEventListener('build', function(e){
// e.target matches the elem from above
}, false);
Ответ 4
Вот действительно простая (TypeScript/Babelish) реализация:
const simpleEvent = <T extends Function>(context = null) => {
let cbs: T[] = [];
return {
addListener: (cb: T) => { cbs.push(cb); },
removeListener: (cb: T) => { let i = cbs.indexOf(cb); cbs.splice(i, Math.max(i, 0)); },
trigger: (<T> (((...args) => cbs.forEach(cb => cb.apply(context, args))) as any))
};
};
Вы используете его следующим образом:
let onMyEvent = simpleEvent();
let listener = (test) => { console.log("triggered", test); };
onMyEvent.addListener(listener);
onMyEvent.trigger("hello");
onMyEvent.removeListener(listener);
Или в классах вроде этого
class Example {
public onMyEvent = simpleEvent(this);
}
Если вы хотите использовать обычный JavaScript, вы можете перевести его с помощью TypeScript игровой площадки.