如何设置Event的EventTarget

HaN*_*riX 15 javascript

如何设置Event 的EventTarget.

var myObj = {foo: 'bar'};
var event = new Event('eventName');
event.target = myObj;
Run Code Online (Sandbox Code Playgroud)

将导致以下错误:

Uncaught TypeError: Cannot set property target of #<Event> which has only a getter
Run Code Online (Sandbox Code Playgroud)

编辑:

我想写这样的东西,我的班级将是target:

class MyClass {

  constructor() {
    this.listeners = {};
  }

  addEventListener(type, callback) {
    if (!(type in this.listeners)) {
      this.listeners[type] = [];
    }
    this.listeners[type].push(callback);
  }

  removeEventListener() {
    if (!(type in this.listeners)) {
      return;
    }
    var stack = this.listeners[type];
    for (var i = 0, l = stack.length; i < l; i++) {
      if (stack[i] === callback) {
        stack.splice(i, 1);
        return this.removeEventListener(type, callback);
      }
    }
  }

  dispatchEvent(event) {
    if (!(event.type in this.listeners)) {
      return;
    }
    var stack = this.listeners[event.type];
    event.target = this;
    for (var i = 0, l = stack.length; i < l; i++) {
      stack[i].call(this, event);
    }
  }

}

let myInstance = new MyClass();
let event = new Event('eventName');
myInstance.dispatchEvent();
Run Code Online (Sandbox Code Playgroud)

更多信息:https://developer.mozilla.org/en/docs/Web/API/EventTarget

小智 16

好的 - 我只是有一个脑波,所以这里的另一个答案对你来说非常顽皮,可能只是工作.(为我工作;)

event.target = myObj你可以试试:而不是这样做:

Object.defineProperty(event, 'target', {writable: false, value: myObj});
Run Code Online (Sandbox Code Playgroud)

我可能在这里错了,但我认为新的target财产隐藏了原来的财产.它与浏览器内部事件调度的工作方式不同,浏览器事件处理代码几乎肯定会忽略它,但它可能足以欺骗依赖的javascript代码Event.target.

另外,请注意在不同的浏览器中测试它,因为某些浏览器可能会将其定义Event.target为不可配置的属性.

  • 这非常适合单元测试,感谢分享:) (4认同)

T.J*_*der 6

关于您的编辑,它显着改变了问题.现在的答案是:不要使用CustomEvent,你试图将它用于非预期用途的东西.只需使用您自己的对象,因为您从不将事件分派给DOM元素.


它在您发送事件时自动设置:

targetElement.dispatchEvent(event);
Run Code Online (Sandbox Code Playgroud)

如果要包含事件元素以外的自定义数据,只需将其添加为属性:

event.data = myObj;
Run Code Online (Sandbox Code Playgroud)

例:

"use strict";
var div = document.getElementById("target");

div.addEventListener(
  "eventName",
  function(e) {
    console.log("e.target:", e.target);
    console.log("e.data:", e.data);
  },
  false
);

var myObj = {foo: "bar"};
var event = new Event("eventName");
event.data = myObj;
div.dispatchEvent(event);
Run Code Online (Sandbox Code Playgroud)
<div id="target"></div>
Run Code Online (Sandbox Code Playgroud)