Javascript 事件currentTarget在setTimeout之后更改
考虑:Javascript 事件currentTarget在setTimeout之后更改,javascript,html,Javascript,Html,考虑: let sel=document.getElementById('mys'); sel.onchange=函数(e){ console.log(e.currentTarget==null);//false 设置超时(e=>{ console.log(e.currentTarget==null);//true },0,e); } 沃尔沃汽车 萨博 梅赛德斯 奥迪 我建议您尝试使用其他浏览器,因为代码正在使用我的浏览器,我看不出代码片段有任何问题。{ console.log(例如curr
let sel=document.getElementById('mys');
sel.onchange=函数(e){
console.log(e.currentTarget==null);//false
设置超时(e=>{
console.log(e.currentTarget==null);//true
},0,e);
}
沃尔沃汽车
萨博
梅赛德斯
奥迪
我建议您尝试使用其他浏览器,因为代码正在使用我的浏览器,我看不出代码片段有任何问题。setTimeout(…,0);
)是很常见的,正确传递事件(包括currentTarget等)的唯一方法似乎是如下所示克隆它
请注意,这只是“足够好”。。。克隆不完全是原始事件,并且它的上下文不同。。。例如,执行clone.stopPropogation()是毫无意义的
如果需要更改克隆上的currentTarget等,请删除!d、 可写| | |!d、 可配置| |!d、 可枚举| |
let sel=document.getElementById('mys');
功能克隆事件(e){
函数ClonedEvent(){};
让clone=new ClonedEvent();
for(让p在e中){
设d=Object.getOwnPropertyDescriptor(e,p);
if(d&(!d.writeable | | |!d.configurable | |!d.enumerable | | d.get | | d.set)){
对象定义属性(克隆,p,d);
}
否则{
克隆[p]=e[p];
}
}
setPrototypeOf(克隆,e);
返回克隆;
}
sel.onchange=函数(e){
console.log(例如currentTarget);
设clone=cloneEvent(e);
设置超时(e=>{
console.log(例如currentTarget);
},0,克隆);
}
沃尔沃汽车
萨博
梅赛德斯
受此启发,我找到了真正的原因:
描述了我在这里部分复制的算法:
要**向目标[…]发送**事件,请运行以下步骤:
[…]
5.如果目标不是relatedTarget或目标是事件的relatedTarget,则:
[…]
9当父项为非空时:
[…]
8.否则,请将target设置为parent,然后:
[…]
9如果parent为非null,则将parent设置为调用parent的get the parent with事件的结果。
[…]
[…]
12将事件的eventPhase属性设置为捕获阶段。
[…]
14对于事件路径中的每个元组,按相反顺序:
1.[…]调用[…]
15对于事件路径中的每个元组,顺序为:
1.如果元组的目标为非null,则将事件的eventPhase属性设置为AT_target。
2.否则,将事件的eventPhase属性设置为冒泡阶段。
3.[…]调用[…]
[…]
6.将事件的eventPhase属性设置为NONE。
7.将事件的currentTarget属性设置为null。
[…]
要**调用**[…]请运行以下步骤:
[…]
5.将事件的currentTarget属性初始化为结构的调用目标。
[…]
因此,在事件处理完所有阶段(捕获、at_target、冒泡)后,将为currentTarget
分配null
let sel=document.getElementById('mys');
sel.onchange=函数({currentTarget}){
console.log(currentTarget==null);//false
设置超时(()=>{
console.log(currentTarget==null);//false
}, 0);
}
沃尔沃汽车
萨博
梅赛德斯
奥迪
仅对可运行代码使用代码段看起来您需要一个闭包:有趣的是,这是一个闭包吗?我以为闭包根本不会将e传递给setTimeout。。。你现在做的是一种生活?为什么这样做?:“[Event.currentTarget]在事件遍历DOM时标识事件的当前目标”。这不是一个静态属性。在事件完成冒泡后,它将计算为null
,这是有意义的。尝试改用event.target
。(只是评论而不是回答,因为我不知道我是否正确。)这是如何回答这个问题的?它似乎只是将它分配给一个变量/常量,并在setTimeout回调中使用它,它就工作了const ct=e.currentTarget
,然后在setTimeout callback.Wow中使用ct
。这是我第一次注意到currentTarget
为空。他们为什么要这样做?因为在整个捕获/在/冒泡阶段完成之后,就不再有currentTarget
,因为再也没有正在处理的目标了。哇x2。我刚刚发现,在所有事件处理程序中都传递了相同的事件对象。这意味着您可以将属性附加到e
,下一个处理程序可以访问这些属性。