Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 事件currentTarget在setTimeout之后更改_Javascript_Html - Fatal编程技术网

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
,下一个处理程序可以访问这些属性。