JavaScript自定义事件侦听器

Lpc*_*ark 42 javascript event-listener

我想知道是否有人可以帮助我理解如何创建不同的自定义事件监听器.

我没有特定的事件案例,但我想一般地了解它是如何完成的,所以我可以在需要的地方应用它.

我想做什么,只是让一些人可能需要知道,是:

var position = 0;

for(var i = 0; i < 10; i++)
{
    position++;
    if((position + 1) % 4 == 0)
    {
        // do some functions
    }
}
Run Code Online (Sandbox Code Playgroud)

Max*_*Max 59

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);
Run Code Online (Sandbox Code Playgroud)

以下是在本地进行更多操作的方法,精确定位听众和出版商:http: //www.kaizou.org/2010/03/generating-custom-javascript-events/

  • **注意:**不推荐使用`createEvent`方法.请改用[`event constructors`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). (8认同)
  • IE中不支持事件构造函数. (4认同)

Rol*_*man 42

实现自定义事件并不难.您可以通过多种方式实现它.最近我这样做:

/***************************************************************
*
*   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;
    }
};
Run Code Online (Sandbox Code Playgroud)

只需将Observable的原型与该构造函数的原型混合,Observable对象就可以被任何构造函数需要重用和应用.

要开始监听,您必须将自己注册到可观察对象,如下所示:

var obs = new Observable();
obs.listen("myEvent", function(observable, eventType, data){
    //handle myEvent
});
Run Code Online (Sandbox Code Playgroud)

或者,如果您的侦听器是对象的方法,如下所示:

obs.listen("myEvent", listener.handler, listener);
Run Code Online (Sandbox Code Playgroud)

listener是一个对象的实例,它实现了方法"handler".

Observable对象现在可以在发生想要与其侦听器通信的事件时调用其fireEvent方法:

this.fireEvent("myEvent", data);
Run Code Online (Sandbox Code Playgroud)

数据是一些听众我觉得有趣的数据.无论你放在哪里都取决于你 - 你最了解你的自定义事件是由什么组成的.

fireEvent方法只是遍历为"myEvent"注册的所有侦听器,并调用已注册的函数.如果函数返回false,那么这意味着事件被取消,并且observable将不会调用其他侦听器.因此,整个fireEvent方法也将返回fasle,因此observable知道现在应该回滚通知其侦听器的任何操作.

也许这个解决方案并不适合所有人,但是我从这个相对简单的代码中获益良多.


new*_*rts 9

从这里:

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);
Run Code Online (Sandbox Code Playgroud)

  • 在同一页面上https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events#Creating_events它提到IE不支持这一点. (4认同)

Cia*_*tic 7

这是一个非常简单的(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))
    };
};
Run Code Online (Sandbox Code Playgroud)

你像这样使用它:

let onMyEvent = simpleEvent();
let listener = (test) => { console.log("triggered", test); };
onMyEvent.addListener(listener);
onMyEvent.trigger("hello");
onMyEvent.removeListener(listener);
Run Code Online (Sandbox Code Playgroud)

或者在这样的班级

class Example {
    public onMyEvent = simpleEvent(this);
}
Run Code Online (Sandbox Code Playgroud)

如果你想要纯 JavaScript,你可以使用TypeScript playground来转换它。