首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >自定义对象上的addEventListener

自定义对象上的addEventListener
EN

Stack Overflow用户
提问于 2013-12-30 08:13:54
回答 14查看 93.1K关注 0票数 68

我创建了一个有几个方法的对象。其中一些方法是异步的,因此我希望使用事件来执行方法完成时的操作。为此,我尝试将addEventListener添加到对象中。

小提琴

代码语言:javascript
运行
复制
var iSubmit = {
    addEventListener: document.addEventListener || document.attachEvent,
    dispatchEvent: document.dispatchEvent,
    fireEvent: document.fireEvent,   


    //the method below is added for completeness, but is not causing the problem.

    test: function(memo) {
        var name = "test";
        var event;
        if (document.createEvent) {
            event = document.createEvent("HTMLEvents");
            event.initEvent(name, true, true);
        } else {
            event = document.createEventObject();
            event.eventType = name;
        }
        event.eventName = name;
        event.memo = memo || { };

        if (document.createEvent) {
            try {
                document.dispatchEvent(event);
            } catch (ex) {
                iAlert.debug(ex, 'iPushError');
            }
        } else {
            document.fireEvent("on" + event.eventType, event);
        }
    }
}

iSubmit.addEventListener("test", function(e) { console.log(e); }, false);


//This call is added to have a complete test. The errors are already triggered with the line before this one.

iSubmit.test();

这将返回一个错误:Failed to add eventlisterens: TypeError: 'addEventListener' called on an object that does not implement interface EventTarget."

现在,这段代码将在phonegap应用程序中使用,当我这样做时,它将在android/ios上运行。不过,在测试期间,如果我能让它至少在一个浏览器中工作,那就太好了。

PS> --我知道我可以启用冒泡,然后监听文档根,但是我希望只有一点OOP,每个对象都可以自己工作。

EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2014-01-03 20:56:52

addEventListener用于实现特定事件相关接口的DOM元素。如果需要纯JavaScript对象上的事件系统,则需要自定义事件系统。一个例子是Backbone.Events in Backbone.js。基本思想是使用对象作为哈希来跟踪已注册的回调。

就我个人而言,我使用的是:发射极

这是一个相当简单和优雅的解决方案--使用on()off()emit()等简短的方法名称。您可以使用new Emitter()创建新实例,也可以使用Emitter(obj)将事件功能混合到现有对象中。注意,这个库是为CommonJS模块系统编写的,但是您可以通过删除module.exports = ...行在其他任何地方使用它。

票数 54
EN

Stack Overflow用户

发布于 2014-01-08 20:51:25

如果您想要侦听javascript对象,您有三种方法:

关于sup/pub模式的

你需要发布事件。

关于本机实现的

  • Object get/set operators足以侦听添加、删除、更改、获取事件。运营商有良好的支持。问题仅在IE8-。但是,如果要在IE8中使用get/set,可以在DOM对象上使用Object.defineProperty,或者使用Object.defineProperty 假的
  • Object.prototype.watch有好的ES5 聚脂填充
  • Proxy API需要ES和谐的支持。

Object.observe示例

代码语言:javascript
运行
复制
var o = {};
Object.observe(o, function (changes) {
  changes.forEach(function (change) {
    // change.object contains changed object version
    console.log('property:', change.name, 'type:', change.type);
  });
});
o.x = 1     // property: x type: add
o.x = 2     // property: x type: update
delete o.x  // property: x type: delete
票数 17
EN

Stack Overflow用户

发布于 2015-06-30 19:12:53

如果您不需要真正的事件特性(如冒泡,stopPropagation),那么您可以实现自己的事件。addEventListener只是DOM的一个API,所以您并不真正需要它来处理DOM之外的自己的对象。如果您想要在对象周围创建一个偶发的模式,那么这里有一个很好的方法,它不需要任何额外的浏览器API,并且应该是非常兼容的。

假设您有一个对象,当调用调度方法时,您希望在其中触发一组事件:

代码语言:javascript
运行
复制
var OurDispatcher, dispatcher;

OurDispatcher = (function() {
  function OurDispatcher() {
    this.dispatchHandlers = [];
  }

  OurDispatcher.prototype.on = function(eventName, handler) {
    switch (eventName) {
      case "dispatch":
        return this.dispatchHandlers.push(handler);
      case "somethingElse":
        return alert('write something for this event :)');
    }
  };

  OurDispatcher.prototype.dispatch = function() {
    var handler, i, len, ref;
    ref = this.dispatchHandlers;
    for (i = 0, len = ref.length; i < len; i++) {
      handler = ref[i];
      setTimeout(handler, 0);
    }
  };

  return OurDispatcher;

})();

dispatcher = new OurDispatcher();

dispatcher.on("dispatch", function() {
  return document.body.innerHTML += "DISPATCHED</br>";
});

dispatcher.on("dispatch", function() {
  return document.body.innerHTML += "DISPATCHED AGAIN</br>";
});

dispatcher.dispatch();

在大多数情况下,这并不需要比这更复杂。这样,您就可以对事件有一些适当的控制,并且不需要担心向后兼容性或外部库,因为那里的所有东西都得到了广泛的支持。从技术上讲,您甚至可以不使用setTimeout来处理回调,而不需要任何API。任何其他类似stopPropagation()的东西都必须自己处理。

https://jsfiddle.net/ozsywxer/

当然,CustomEvent有多填充功能,但除非我需要高级事件特性,否则我更喜欢将自己的事件系统包装成一个“类”,并使用它扩展其他类/函数。

以下是CoffeeScript版本,这是JavaScript的来源:https://jsfiddle.net/vmkkbbxq/1/

有点容易理解。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20835768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档