普通的Javascript对象可以有事件吗?

时间:2010-01-18 15:15:55

标签: javascript object events

普通的Javascript对象可以附加事件吗?说这样的话:

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

我知道我可以用jQuery做到这一点,但是没有任何库可以吗?

9 个答案:

答案 0 :(得分:10)

你必须为此实现自己的功能,但这并不是很难。

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');
    }
};

答案 1 :(得分:5)

没有

但是,您可以通过编写addEventListener和其他函数以及为每个事件存储处理程序列表来实现自己的实现。

例如:(未经测试)

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;

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

不,JavaScript对象唯一拥有的是属性。这些属性的值可能是:

  • 原始值
  • 对象(包括功能对象)

答案 6 :(得分:1)

最近,这实际上是可能的!

但是,它没有出色的浏览器支持。请参见该图的“ EventTarget()构造函数”部分:plot obtained

或者查看仅包含相关行的此图:https://developer.mozilla.org/en-US/docs/Web/API/EventTarget#Browser_compatibility

无论哪种情况,您要做的就是让类扩展EventTarget,并确保您在构造函数中调用super()。完成之后,您可以调度和侦听DOM对象上的事件。

示例代码:

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();

答案 7 :(得分:0)

不,不是您可以向任何对象添加事件处理程序。如果你正在为其他脚本编写某种API或库来与之交互,你可以为对象编写自己的事件系统。

答案 8 :(得分:0)

您可以定义addEventListener方法来收集所有侦听器对象,您的代码可以随时调用它们。这只是OO编程。定义addXListener,在某处添加作为参数传递的对象,当发生某些事情时,你可以调用它的方法。

但请记住,UI事件是由HTML / Javascript定义的事件,因此您编程的内容仅适用于您的“obj”对象以提醒您的事件。

以示例:

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

并且doSuff将首先调用启动侦听器,然后执行一些循环并为每个迭代调用处理侦听器,并在结束时调用结束侦听器。