简体   繁体   中英

Can plain Javascript objects have events?

Can plain Javascript objects have event attached to them? Say something like this:

obj = new Object();
obj.addEventListener('doSomething', foo, true);

I know i can do this with jQuery, but is it possible without any library?

You'll have to implement your own functionality for that, but that's not very hard.

var obj = {
    events: {},
    addEventListener: function(eventName, handler) {
        if(!(eventName in this.events))
            this.events[eventName] = [];

        this.events[eventName].push(handler);
    },

    raiseEvent: function(eventName, args) {
        var currentEvents = this.events[eventName];
        if(!currentEvents) return;

        for(var i = 0; i < currentEvents.length; i++) {
           if(typeof currentEvents[i] == 'function') {
              currentEvents[i](args);
           }
        }
    },

    click: function() {
        // custom 'click' function. when this is called, you do whatever you
        // want 'click' to do. and then raise the event:

        this.raiseEvent('onClick');
    }
};

No.

However, you could make your own implementation by writing addEventListener and other functions and storing a list of handlers for each event.

For example: (Untested)

function addEventListener(name, handler) {
    if (!this.events) this.events = {};
    if (!this.events[name]) this.events[name] = [];
    this.events[name].push(handler);
}

function removeEventListener(name, handler) {
    if (!this.events) return;
    if (!this.events[name]) return;
    for (var i = this.events[name].length - 1; i >= 0; i--)
        if (this.events[name][i] == handler)
            this.events[name].splice(i, 1);
}

function raiseEvent(name, args) {
    if (!this.events) return;
    if (!this.events[name]) return;
    for (var i = 0; i < this.events[name].length; i++)
        this.events[name][i].apply(this, args);
}


var obj = ...;
obj.addEventListener = addEventListener;
obj.removeEventListener = removeEventListener;
obj.raiseEvent = raiseEvent;

不是直接,而是将所需的publish/subscribe基础结构添加到其中任何一个。

不。 addEventListener是 DOM 的一个特性,而不是 JS。

我想你会发现在普通的 JavaScript 中,只有 DOM 对象可以有事件。

No, the only thing that JavaScript objects have is properties. The values of these properties may be:

  • A primitive value
  • An object (including a function object)

As of recent, this is actually possible!

It doesn't have amazing browser support however. See "EventTarget() constructor" part of this graph: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget#Browser_compatibility

Or look at this graph which only contains the relevant row: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/EventTarget#Browser_compatibility

In either case, all you need to do is have your class extend EventTarget, and ensure that you call super() in the constructor. After that's done, you can dispatch and listen for events like on DOM objects.

Sample code:

class EventDispatcher extends EventTarget {
    constructor() {
        super();
    }

    dispatch_event() {
        this.dispatchEvent(new Event("important-notification"));
    }
}

const event_dispatcher = new EventDispatcher();

event_dispatcher.addEventListener("important-notification", function() {
    console.log("Something important happened!");
});

event_dispatcher.dispatch_event();

No, not to the extent that you can add an event handler to any object. You could write your own event system for objects though, if you're writing some sort of API or library for other scripts to interact with.

You can define an addEventListener method to collect all the listener objects, and your code can call them anytime. It's just OO programming. Define the addXListener, add the object passed as parameter somewhere, and when something happens you call it's methods.

Yes.

But remember that UI events are those defined by HTML/Javascript so what you'd be programming will be only for your "obj" object to alert about YOUR events.

By example:

FunnyProcessor
+ addStartListener(...)
+ addProcessingListener(...)
+ addEndListener(...)
+ doStuff()

and doSuff will call first the start listeners, next do some loop and for each iteration call processing listeners, and at the end call end listeners.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM