Javascript 如何设置事件的EventTarget

Javascript 如何设置事件的EventTarget,javascript,Javascript,如何设置事件的名称 var myObj = {foo: 'bar'}; var event = new Event('eventName'); event.target = myObj; 将导致以下错误: Uncaught TypeError: Cannot set property target of #<Event> which has only a getter 更多信息:关于您的编辑,它显著地改变了问题。现在的答案是:不要使用CustomEvent,您试图将其用于其预期用

如何设置事件的名称

var myObj = {foo: 'bar'};
var event = new Event('eventName');
event.target = myObj;
将导致以下错误:

Uncaught TypeError: Cannot set property target of #<Event> which has only a getter

更多信息:

关于您的编辑,它显著地改变了问题。现在的答案是:不要使用
CustomEvent
,您试图将其用于其预期用途之外的其他用途。只需使用您自己的对象,因为您从不将事件分派给DOM元素


当您分派事件时,会自动设置:

targetElement.dispatchEvent(event);
如果要在事件中包含除元素之外的自定义数据,只需将其添加为属性:

event.data = myObj;
例如:

“严格使用”;
var div=document.getElementById(“目标”);
div.addEventListener(
“事件名称”,
职能(e){
日志(“e.target:,e.target”);
日志(“e.data:”,e.data);
},
假的
);
var myObj={foo:bar};
var事件=新事件(“事件名称”);
event.data=myObj;
部门调度事件(事件)

距离你最初的问题已经一年零九个月了,我想用完全相同的代码,从完全相同的地方来做这件事。我确切地知道为什么要这样做,因为
EventTarget
在所有浏览器中都不是可构造的对象。看来你的问题没有真正的解决办法

如果其他任何人遇到此问题并偶然发现此页面,解决方法是不要依赖
Event.target
。您可以创建自定义事件并按如下方式发送它:

var myeventtarget = new MyClass();

var ev = new CustomEvent('myevent', {
    detail: {
        target: myeventtarget
    }});

myeventtarget.dispatchEvent(ev);
class MyClass extends EventTarget {
    constructor() {
        super()
    }
}
然后,在事件处理程序中,可以通过以下方式访问目标:

var event_handler = function(ev) {
    var target = ev.detail.target;
    alert(target);
}
这确实是一个丑陋的语法,但它看起来是目前唯一可以实现的“正确”方法。现在,如果忽略较旧的浏览器,我知道在较新的Firefox和Chrome浏览器中,可以实现如下
MyClass

var myeventtarget = new MyClass();

var ev = new CustomEvent('myevent', {
    detail: {
        target: myeventtarget
    }});

myeventtarget.dispatchEvent(ev);
class MyClass extends EventTarget {
    constructor() {
        super()
    }
}
鉴于上述定义,我还没有测试在
MyClass
类型的对象上调度时是否设置了事件目标,但如果没有,则建议将其作为DOM生活标准的一个更改,因为它显然是有意义的。(规范目前似乎没有建议它应该工作)

最后,我要提醒您,不要在未检查代码是否正常工作的情况下使用您正在使用的javascript
EventTarget
代码。我发现当你给它一个
EventListener
对象时,它会断裂。如果您将同一事件提交两次到
addEventListener()
,它还会附加一个重复的事件,而DOM生活标准明确规定它不能这样做。幸运的是,解决这些问题非常容易。您需要更改
stack[i]。调用(this,event)至:

if (stack[i].handleEvent) stack[i].handleEvent(event);
        else stack[i].call(this, event);
并添加以下内容:

var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
    if (stack[i] === callback){
        return;
    }
}
var stack=this.listeners[type];
for(var i=0,l=stack.length;i
this.listeners[type].push(回调)之前


其他问题是
addEventListener()
如果你给它一个空回调(另一个简单的修复方法),它不会简单地返回,而且显然它不允许向它提交选项。(但请确定您是否真的需要此功能)

好吧,我刚刚灵机一动,这里有另一个答案供您参考,它非常顽皮,可能会奏效。(为我工作;)

您可以尝试以下操作,而不是执行
event.target=myObj

Object.defineProperty(event, 'target', {writable: false, value: myObj});
这里我可能错了,但我认为新的
target
属性隐藏了原始属性。它的工作方式与浏览器内部事件调度不同,浏览器事件处理代码几乎肯定会忽略它,但这可能足以愚弄依赖于
event.target
的javascript代码


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

我可能有误解,但
EventTarget
通常由浏览器自动设置为触发事件的元素。你想做什么?从您问题中有限的信息来看,您应该使用
EventTarget.addEventListener()
,但到目前为止,我非常非常不确定您的意图。我不希望doElement成为EventTarget。相反,它应该是我选择的对象。@HaNdTriX:您的编辑极大地改变了问题,几乎足以使它回滚。(不允许在有答案后从根本上改变一个问题。我认为这仅仅是侥幸通过。)我编辑了答案以解决新问题。我从未提到过DOM元素。我试图把我的问题缩小到最重要的部分。在Javascript中,有许多例子表明事件的目标不是DOM元素。(例如:通知事件)很抱歉不清楚。@HaNdTriX:您链接到特定于web的界面,并在代码中使用了
new Event
。这显然是一个关于DOM事件的问题。您最新的问题是关于您自己的发布/订阅系统。无论如何,答案是:不要使用
CustomEvent
(或
Event
)。不要“只是将其添加为属性”-查看
。详细信息
字段这非常适合单元测试,感谢分享:)