Javascript 自定义对象上的addEventListener
我已经创建了一个具有多个方法的对象。其中一些方法是异步的,因此我希望在方法完成时使用事件来执行操作。为此,我尝试将addEventListener添加到对象中 这将返回一个错误:Javascript 自定义对象上的addEventListener,javascript,object,cordova,addeventlistener,Javascript,Object,Cordova,Addeventlistener,我已经创建了一个具有多个方法的对象。其中一些方法是异步的,因此我希望在方法完成时使用事件来执行操作。为此,我尝试将addEventListener添加到对象中 这将返回一个错误:未能添加EventListens:TypeError:“addEventListener”在未实现接口EventTarget的对象上调用。“ 现在,这段代码将在phonegap应用程序中使用,当我这样做时,它将在android/ios上工作。然而,在测试期间,如果我能让它在至少一个浏览器中工作,那就太好了 PS>我知道
未能添加EventListens:TypeError:“addEventListener”在未实现接口EventTarget的对象上调用。“
现在,这段代码将在phonegap应用程序中使用,当我这样做时,它将在android/ios上工作。然而,在测试期间,如果我能让它在至少一个浏览器中工作,那就太好了
PS>我知道我可以启用冒泡,然后监听文档根,但我希望有一点OOP,每个对象都可以独立工作。我认为可以使用object$Deferred和promises。 它会让你做这样的事情: 堆叠:将应用程序中任意位置的多个处理程序绑定到同一承诺事件
var request = $.ajax(url);
request.done(function () {
console.log('Request completed');
});
//应用程序中的其他地方
request.done(function (retrievedData) {
$('#contentPlaceholder').html(retrievedData);
});
并行任务:要求多个承诺返回一个承诺,该承诺提醒双方完成
$.when(taskOne, taskTwo).done(function () {
console.log('taskOne and taskTwo are finished');
});
顺序任务:按顺序执行任务
var step1, step2, url;
url = 'http://fiddle.jshell.net';
step1 = $.ajax(url);
step2 = step1.then(
function (data) {
var def = new $.Deferred();
setTimeout(function () {
console.log('Request completed');
def.resolve();
},2000);
return def.promise();
},
function (err) {
console.log('Step1 failed: Ajax request');
}
);
step2.done(function () {
console.log('Sequence completed')
setTimeout("console.log('end')",1000);
});
资料来源:
本文介绍如何创建自定义事件: 以下是一个例子: 创建事件-
var event = new CustomEvent(
"newMessage",
{
detail: {
message: "Hello World!",
time: new Date(),
},
bubbles: true,
cancelable: true
}
);
将事件分配给以下对象:
document.getElementById("msgbox").dispatchEvent(event);
订阅活动-
document.addEventListener("newMessage", newMessageHandler, false);
addEventListener
适用于实现某些事件相关接口的DOM元素。如果您想要纯JavaScript对象上的事件系统,您需要一个自定义事件系统。例如Backbone.js中的Backbone.Events
。基本思想是使用对象作为哈希来跟踪已注册的c全能球员
就我个人而言,我使用这个:
这是一个相当简单而优雅的解决方案-使用简短的方法名,如
on()
、off()
和emit()
。您可以使用new Emitter()
创建新实例,也可以使用Emitter(obj)
将事件功能混合到现有对象中。请注意,此库是为与CommonJS模块系统一起使用而编写的,但您可以通过删除module.exports=…
行在其他任何地方使用它。存在两个问题
首先,iSubmit.addEventListener()
方法实际上是EventTarget
DOM接口上的一个方法:
iSubmit
对象中,您正在对不是EventTarget
的对象调用它。这就是为什么Chrome抛出未捕获类型错误:非法调用
JavaScript错误
第一个问题很关键,但是如果您可以使用EventTarget#addEventListener()
,您的代码将无法工作,因为事件将被添加到iSubmit
,但从document
发送。通常,在附加事件侦听器和发送事件时需要使用相同对象的方法(除非您使用冒泡事件,注意:冒泡并不限于JavaScript或DOM相关事件,)
对您自己的对象使用自定义事件是非常正常的。因此,有一些库可用于此操作。以下是几个库:
jssignals
,并且非常喜欢它。我从未使用过Wolfy87/EventEmitter
,但是它看起来很不错
如果您使用了js信号,那么您的示例可能类似于以下内容
如果要侦听javascript对象,有三种方法:
- 使用在javascript中有很多功能的
- 或通过使用本机实现,或
- 使用.Works Chrome 25+(2014年1月)。但在2016年成为
关于sup/pub模式:
const CustomObject = require('./CustomObject');
// 1. Create a new instance
const myObject = new CustomObject();
// 2. Subscribe to events with ID "myEventName"
myObject.on('myEventName', function(event) {
console.log('Received event', event);
});
// 3. Trigger the event emitter
myObject.doSomething();
您需要发布事件
关于本机实现:
const CustomObject = require('./CustomObject');
// 1. Create a new instance
const myObject = new CustomObject();
// 2. Subscribe to events with ID "myEventName"
myObject.on('myEventName', function(event) {
console.log('Received event', event);
});
// 3. Trigger the event emitter
myObject.doSomething();
对象获取/设置运算符
足以侦听添加、删除、更改、,
获取事件。运算符有好的。问题仅限于IE8-。
但是如果您想在IE8中使用get/set,请使用Object.defineProperty
But
在DOM对象上或使用Object.defineProperty
Object.prototype.watch
具有良好的ES5性能
代理API
需要ES Harmony支持
对象。观察示例
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
如果您不需要真正的事件功能(例如冒泡、停止冒泡),然后您可以实现自己的事件。addEventListener只是DOM的一个API,因此您在DOM之外的对象中并不真正需要它。如果您想围绕对象创建事件模式,下面是一个很好的方法,它不需要任何额外的浏览器API,并且应该非常向后兼容
假设您有一个对象,希望在调用dispatch方法时触发一组事件:
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();
var调度程序,调度程序;
OurDispatcher=(函数(){
函数OurDispatcher(){
this.dispatchHandlers=[];
}
OurDispatcher.prototype.on=函数(eventName,handler){
开关(eventName){
“派遣”一案:
返回此.dispatchHandlers.push(处理程序);
案例“somethingElse”:
返回警报(“为此事件写入内容:)”;
}
};
OurDispatcher.prototype.dispatch=函数(){
变量处理程序,i,len,ref;
ref=这是dispatchHandlers;
对于(i=0,len=ref.length;i”;
});
dispatcher.on(“dispatch”,function()){
return document.body.innerHTML+=“再次发送””;
});
dispatcher.dispatch();
在大多数情况下,它真的不必比那复杂。这样你就有了一些d
const EventEmitter = require('events');
class CustomObject extends EventEmitter {
constructor() {
super();
}
doSomething() {
const event = {message: 'Hello World!'};
this.emit('myEventName', event);
}
}
module.exports = CustomObject;
const CustomObject = require('./CustomObject');
// 1. Create a new instance
const myObject = new CustomObject();
// 2. Subscribe to events with ID "myEventName"
myObject.on('myEventName', function(event) {
console.log('Received event', event);
});
// 3. Trigger the event emitter
myObject.doSomething();
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Title</title>
<script src="bundle.js"></script>
</head>
<body>
<script>
// 1. Create a new instance
const myObject = new window.CustomObject();
// 2. Subscribe to events with ID "myEventName"
myObject.on('myEventName', function(event) {
console.log('Received event', event);
});
// 3. Trigger the event emitter
myObject.doSomething();
</script>
</body>
</html>
function myObject(){
//create "dummy" element
var dummy = document.createElement('dummy');
//method for listening for events
this.on = function(event, func){dummy.addEventListener(event, func);};
//you need a way to fire events
this.fireEvent = function(event, obj){
dummy.dispatchEvent(new CustomEvent(event, {detail: obj}));
}
}
//now you can use the methods in the object constructor
var obj = new myObject();
obj.on("custom", function(e){console.log(e.detail.result)});
obj.fireEvent("custom", {result: "hello world!!!"});
CustomEventTarget.prototype = {
'constructor': CustomEventTarget,
on: function( ev, el ) { this.eventTarget.addEventListener( ev, el ) },
off: function( ev, el ) { this.eventTarget.removeEventListener( ev, el ) },
emit: function( ev ) { this.eventTarget.dispatchEvent( ev ) }
}
function CustomEventTarget() { this.eventTarget = new EventTarget }
class Events {
constructor () {
this._callbacks = {}
}
on (key, callback) {
// create an empty array for the event key
if (this._callbacks[key] === undefined) { this._callbacks[key] = [] }
// save the callback in the array for the event key
this._callbacks[key].push(callback)
}
emit (key, ...params) {
// if the key exists
if (this._callbacks[key] !== undefined) {
// iterate through the callbacks for the event key
for (let i=0; i<this._callbacks[key].length; i++) {
// trigger the callbacks with all provided params
this._callbacks[key][i](...params)
}
}
}
}
// EXAMPLE USAGE
class Thing extends Events {
constructor () {
super()
setInterval(() => {
this.emit('hello', 'world')
}, 1000)
}
}
const thing = new Thing()
thing.on('hello', (data) => {
console.log(`hello ${data}`)
})
/*
* object.watch polyfill
*
* 2012-04-03
*
* By Eli Grey, http://eligrey.com
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
* https://gist.github.com/eligrey/384583
*/
// object.watch
if (!Object.prototype.watch) {
Object.defineProperty(Object.prototype, "watch", {
enumerable: false
, configurable: true
, writable: false
, value: function (prop, handler) {
var
oldval = this[prop]
, newval = oldval
, getter = function () {
return newval;
}
, setter = function (val) {
oldval = newval;
return newval = handler.call(this, prop, oldval, val);
}
;
if (delete this[prop]) { // can't watch constants
Object.defineProperty(this, prop, {
get: getter
, set: setter
, enumerable: true
, configurable: true
});
}
}
});
}
// object.unwatch
if (!Object.prototype.unwatch) {
Object.defineProperty(Object.prototype, "unwatch", {
enumerable: false
, configurable: true
, writable: false
, value: function (prop) {
var val = this[prop];
delete this[prop]; // remove accessors
this[prop] = val;
}
});
}
var object = {
value: null,
changeValue: function(newValue) {
this.value = newValue;
},
onChange: function(callback) {
this.watch('value', function(obj, oldVal, newVal) {
// obj will return the object that received a change
// oldVal is the old value from the object
// newVal is the new value from the object
callback();
console.log("Object "+obj+"'s value got updated from '"+oldValue+"' to '"+newValue+"'");
// object.changeValue("hello world");
// returns "Object object.value's value got updated from 'null' to 'hello world'";
// and if you want the function to stop checking for
// changes you can always unwatch it with:
this.unwatch('value');
// you can retrieve information such as old value, new value
// and the object with the .watch() method, learn more here:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch
})
}
};
var object = { user: null };
// add a watch to 'user' value from object
object.watch('user', function() {
// object user value changed
});
class EventEmitter {
on(name, callback) {
var callbacks = this[name];
if (!callbacks) this[name] = [callback];
else callbacks.push(callback);
}
dispatch(name, event) {
var callbacks = this[name];
if (callbacks) callbacks.forEach(callback => callback(event));
}
}
var emitter = new EventEmitter();
emitter.on('test', event => {
console.log(event);
});
emitter.dispatch('test', 'hello world');
class MyClass
{
constructor(options )
{
this.el = document.createElement("MyClass");//dummy element to manage events.
this.el.obj= this; //So that it is accessible via event.target.obj
}
addEventListener()
{
this.el.addEventListener(arguments[0],arguments[1]);
}
raiseEvent()
{
//call this function or write code below when the event needs to be raised.
var event = new Event('dataFound');
event.data = messageData;
this.el.dispatchEvent(event);
}
}
let obj = new MyClass();
obj.addEventListener('dataFound',onDataFound);
function onDataFound()
{
console.log('onDataFound Handler called');
}