问题描述
考虑:
let sel=document.getElementById('mys');
sel.onchange=function(e) {
console.log(e.currentTarget===null); // false
setTimeout(e => {
console.log(e.currentTarget===null); // true
}, 0, e);
}
<select id="mys">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
-
为什么e.currentTarget在超时后发生变化?是浏览器(chrome)错误吗?
why does e.currentTarget changes after the timeout ? is that a browser (chrome) bug ?
如何将事件的精确副本转移到超时功能?我尝试了简单的克隆,但是currentTarget不可写,不能被ovverridden ..
how can I transfer an exact clone of the event to the timeout function ? I tried simple cloning but currentTarget is not writable and cannot be ovverridden ..
推荐答案
event.currentTarget和其他一些属性在退出事件处理程序后会更改.
event.currentTarget and some other properties change after exiting the event handler.
在事件处理程序中执行上下文切换(setTimeout(... ,0);
)很常见,看来正确传递包括currentTarget等事件的唯一方法是按如下所示对其进行克隆.
Doing a context switch (setTimeout(... ,0);
) in an event handler is common, it seems that the only way to correctly pass the event including currentTarget etc is to clone it as below.
请注意,这仅仅是足够好" ...克隆并不完全是原始事件,它的上下文是不同的...例如执行clone.stopPropogation()毫无意义...
Note that this is only 'good enough' ... the clone is not exactly the original event, and it's context is different ... doing for example clone.stopPropogation() is meaningless ...
如果您需要更改克隆上的currentTarget等,请删除!d.writable || !d.configurable || !d.enumerable ||
If you need to change currentTarget etc on the clone delete !d.writable || !d.configurable || !d.enumerable ||
let sel=document.getElementById('mys');
function cloneEvent(e) {
function ClonedEvent() {};
let clone=new ClonedEvent();
for (let p in e) {
let d=Object.getOwnPropertyDescriptor(e, p);
if (d && (!d.writable || !d.configurable || !d.enumerable || d.get || d.set)) {
Object.defineProperty(clone, p, d);
}
else {
clone[p] = e[p];
}
}
Object.setPrototypeOf(clone, e);
return clone;
}
sel.onchange=function(e) {
console.log(e.currentTarget);
let clone=cloneEvent(e);
setTimeout(e => {
console.log(e.currentTarget);
}, 0, clone);
}
<select id="mys">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
</select>
这篇关于setTimeout之后事件currentTarget发生更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!