onclick = xxx这种赋值写法绑定事件的原理是什么?

本文转自知乎貘吃馍香的回答

提问:刚入门不久,能力有限,这个问题我描述起来有点困难,只有劳烦各位大神细看了

我之前一直以为js底层存在类似下面这样的代码:

//给所有dom对象定义好onclick值为一个空函数
HTMLElement.prototype.onclick = function(){}; //给所有dom对象绑定默认点击回调函数:点击时都执行一次自己的onclick方法 [].map.call(document.all,function(item){ item.addEventListener('click',function(){ this.onclick(); }); }); 

然后我认为给同一个元素多次添加事件函数,会形成一个待执行的函数队列,那么onclick以后无论怎么赋值,执行顺序会相对固定。
然而有如下可运行的代码我又无法解释(请展开全部之后再阅读代码,避免混乱):

//改变onclick的函数。此时body['click']的事件队列第一个函数为alert(1);
document.body.onclick = function(){alert(1)} //body['click']事件队列里增加了alert(2);点击时依次执行alert(1)、alert(2) document.body.addEventListener('click',function(){alert(2)}); //再改变onclick的函数。此时body['click']的事件队列第一个函数换为alert(3); document.body.onclick = function(){alert(3)} 

然后这时候点击body,先后顺序本应该是alert(3)、alert(2),实际却是alert(3)在后面?
为什么仅仅凭一个赋值操作改变了onclick的值就能导致事件执行的顺序变了呢?
是“队列”的思想错误了,还是οnclick=xxx,不是我想的那么简单?

补充后续思考:

如果onclick赋值时有内部操作改变了执行函数的队列,那js为什么要这么做呢?

 


 

 

貘吃馍香

路过
不同浏览器不一定是这个结果
底层代码肯定不是JS

仅趴了机器上几年前最老的blink代码看了下
EventListenerMap 里靠的是 EventListenerVector
这玩意就是个 Vector
typedef Vector<RegisteredEventListener, 1>
这么搞的

onclick setting 时候是 vector->find 后没有对应 handle
再 append 进去的
再次 setting 时是 find 有
就先 remove 老的再 append
没见 Vector 有用到(定义过) replace 方法

所以(在这么实现的浏览器上)才有这种现象

最终还是轮子哥猜对了。

vczh
合理猜测:给onclick赋值的内部操作时,remove掉原来的,add上新的。

转载于:https://www.cnblogs.com/Tjinhui/p/6704872.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值