我创建了一个有几个方法的对象。其中一些方法是异步的,因此我希望使用事件来执行方法完成时的操作。为此,我尝试将addEventListener添加到对象中。
小提琴
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,每个对象都可以自己工作。
发布于 2014-01-03 20:56:52
addEventListener用于实现特定事件相关接口的DOM元素。如果需要纯JavaScript对象上的事件系统,则需要自定义事件系统。一个例子是Backbone.Events in Backbone.js。基本思想是使用对象作为哈希来跟踪已注册的回调。
就我个人而言,我使用的是:发射极。
这是一个相当简单和优雅的解决方案--使用on()、off()和emit()等简短的方法名称。您可以使用new Emitter()创建新实例,也可以使用Emitter(obj)将事件功能混合到现有对象中。注意,这个库是为CommonJS模块系统编写的,但是您可以通过删除module.exports = ...行在其他任何地方使用它。
发布于 2014-01-08 20:51:25
如果您想要侦听javascript对象,您有三种方法:
Object get/set operators、Object.defineProperty、Object.prototype.watch或Proxy API使用本机实现。Object.observe。Works Chrome 25+(2014年1月)。但在2016年成为已弃用关于sup/pub模式的:
你需要发布事件。
关于本机实现的:
Object get/set operators足以侦听添加、删除、更改、获取事件。运营商有良好的支持。问题仅在IE8-。但是,如果要在IE8中使用get/set,可以在DOM对象上使用Object.defineProperty,或者使用Object.defineProperty 假的。Object.prototype.watch有好的ES5 聚脂填充。Proxy API需要ES和谐的支持。Object.observe示例
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发布于 2015-06-30 19:12:53
如果您不需要真正的事件特性(如冒泡,stopPropagation),那么您可以实现自己的事件。addEventListener只是DOM的一个API,所以您并不真正需要它来处理DOM之外的自己的对象。如果您想要在对象周围创建一个偶发的模式,那么这里有一个很好的方法,它不需要任何额外的浏览器API,并且应该是非常兼容的。
假设您有一个对象,当调用调度方法时,您希望在其中触发一组事件:
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/
有点容易理解。
https://stackoverflow.com/questions/20835768
复制相似问题