setTimeout之后事件currentTarget发生更改 [英] event currentTarget changes after setTimeout

查看:61
本文介绍了setTimeout之后事件currentTarget发生更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑:

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发生更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆