zoukankan      html  css  js  c++  java
  • 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的值就能导致事件执行的顺序变了呢?
    是“队列”的思想错误了,还是onclick=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上新的。
  • 相关阅读:
    djongo 前端页面展示自定义api返回的列表数据,并拼接到table上
    ou are trying to add a non-nullable field 'address' to person without a default; we can't do that (the database needs something to populate existing rows).
    python string 类型的公钥转换类型并解密
    Django 禁止访问403,CSRF验证失败,相应中断
    springboot async
    此博客可能不再更新,往后博文将发布在 GitHub 中
    css 中 transition 需要注意的问题
    学习笔记(九)
    微信小程序 drawImage 问题
    学习笔记(八)
  • 原文地址:https://www.cnblogs.com/Tjinhui/p/6704872.html
Copyright © 2011-2022 走看看