JavaScript自定义事件监听器
我想知道是否有人可以帮助我了解如何创build不同的自定义事件侦听器。
我没有一个具体的事件的例子,但是我想一般地学习它是如何完成的,所以我可以将它应用在需要的地方。
我想要做的事情,只是一些人可能需要知道,是:
var position = 0; for(var i = 0; i < 10; i++) { position++; if((position + 1) % 4 == 0) { // do some functions } }
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/
实现自定义事件并不困难。 你可以用很多方式来实现它。 最近我是这样做的:
/*************************************************************** * * 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对象可以被任何构造函数所需要的重用和应用。
要开始聆听,您必须注册自己到可观察对象,如下所示:
var obs = new Observable(); obs.listen("myEvent", function(observable, eventType, data){ //handle myEvent });
或者如果你的监听器是一个对象的方法,像这样:
obs.listen("myEvent", listener.handler, listener);
其中listener是一个实现了“handler”方法的对象实例。
Observable对象现在可以调用它的fireEvent方法,只要有事情发生,它想要与其监听器进行通信:
this.fireEvent("myEvent", data);
数据是我听到的有趣数据。 无论你放在哪里,都取决于你 – 你最了解你的自定义事件是由什么组成的。
fireEvent方法简单地遍历所有为“myEvent”注册的侦听器,并调用已注册的函数。 如果函数返回false,则意味着该事件被取消,并且observable将不会调用其他侦听器。 因此,整个fireEvent方法也会返回,所以观察者知道无论是通知其监听者的操作现在都应该被回滚。
也许这个解决scheme并不适合每个人,但是我从这个相对简单的代码中获益颇多。
从这里:
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);
这是一个非常简单的(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操作系统来传输它。