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

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

我之前一直以为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上新的。

onclick = xxx这种赋值写法绑定事件的原理是什么?的更多相关文章

  1. 面试时被问到js的绑定事件,我居然不知道怎么回答。回来查了下,做个笔记

    事件绑定是几种方法 以下为例: <button id='btn'>click me</button> function Btn(){ alert('click'); } 1.直 ...

  2. JavaScript中给onclick绑定事件后return false遇到的问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. js绑定事件方法:addEventListener与attachEvent的不同浏览器的兼容性写法

    js的事件绑定方法中,ie仅仅支持attachEvent,而FF和Chrome仅仅支持addEventListener,所以就必须为这两个方法做兼容处理,原理是先推断attachEvent仅仅否为真( ...

  4. 原生JS事件绑定方法以及jQuery绑定事件方法bind、live、on、delegate的区别

    一.原生JS事件绑定方法: 1.通过HTML属性进行事件处理函数的绑定如: <a href="#" onclick="f()"> 2.通过JavaS ...

  5. JQuery在循环中绑定事件的问题详解

    JQuery在循环中绑定事件的问题详解 有个页面上需要N个DOM,每个DOM里面的元素ID都要以数字结尾,比如说 ? 1 2 3 <input type="text" nam ...

  6. jQuery delegate方法实现Ajax请求绑定事件不丢失

    给元素绑定click事件后 ,遇到一个问题:当执行一些ajax请求,再次调用此页面,里面的这个click事件就失效了 比如说:我的分页是一个ajax请求 但我点下一页时 后生成的元素a就没有了clic ...

  7. JavaScript绑定事件的方法[3种]

    在JavaScript中,有三种常用的绑定事件的方法: 在DOM元素中直接绑定: 在JavaScript代码中绑定: 绑定事件监听函数. 一. 在DOM元素中直接绑定 这里的DOM元素,可以理解为HT ...

  8. Xamarin.Android中使用android:onClick="xxx"属性

    原文:Xamarin.Android中使用android:onClick="xxx"属性 在原生Android开发中,为一个View增加点击事件,有三种方式: 1.使用匿名对象 ( ...

  9. dom元素循环绑定事件的技巧

    以前总觉得自己写的代码不太规范,尤其是写原生的时候.举个例子: 要为页面上所有".a"的元素绑定事件,当然了用jquery很方便:$('.a').bind("click& ...

随机推荐

  1. java.lang.ClassNotFoundException: org.apache.commons.logging.Log

    严重: A child container failed during startjava.util.concurrent.ExecutionException: org.apache.catalin ...

  2. Ubuntu 小白安装血泪史

    介绍: 新入手的Ubuntu:版本 命令行模式下 出现 ♦♦♦♦ 图形界面无法获取最高权限:gurb.cfg 无法再图形界面下修改 安装类型: 1.安装Ubuntu,与Window 7共存 2.清除整 ...

  3. 关于adb重启的一些问题

    有时候我们在使用eclipse启动虚拟机进行程序测试的时候会提示,要我们重启adb和eclipse,这个时候,重启adb的方式就是,使用cmd定位到adb所在的文件夹,然后输入指令:adb kill- ...

  4. 关于CSS各种选择器,还有各种引入样式表的区别,import导入样式表,在介绍一些伪类选择器

    (一)CSS选择器: 1.标签选择器:通过HTML的标签名直接选择该标签 2.类选择器:通过.选择器的名称{} 来对添加了class属性的标签进行选中 3.ID选择器:通过#选择器的名称{} 来对添加 ...

  5. API抓屏

    需调用API函数 需在开头引入命名空间 using System.Runtime.InteropServices; 获取当前窗口句柄:GetForegroundWindow() [DllImport( ...

  6. Spring RESTful + Redis全注解实现恶意登录保护机制

    好久没更博了... 最近看了个真正全注解实现的 SpringMVC 博客,感觉很不错,终于可以彻底丢弃 web.xml 了.其实这玩意也是老东西了,丢弃 web.xml,是基于 5.6年前发布的 Se ...

  7. 解决https证书验证不通过的问题

    1.报错信息 java.security.cert.CertificateException: No name matching api.weibo.com found; nested excepti ...

  8. 【杂】poj2482 Stars in Your Windows 题面的翻译

    原地址:http://poj.org/problem?id=2482 神题,被誉为最浪漫的题目,一位acmer以自己独特的方式写下的殷殷情语 你窗前的星星 纵时光飞逝如梭,也我对你的回忆也永不黯然.从 ...

  9. 【原】cookie小结

    前记:前段时间搞一个活动,开发的时间被严重压缩,忙到飞起,以致于都没怎么写文章了,内疚. 2月份参加了一场面试,有一些关于cookie的问题回答的不是很好,所以这篇文章我们来对cooKie做一个探讨和 ...

  10. 关于label和input对齐的那些事

    input文本和label对齐 默认状态下,也就是下面这样, 文字和input是居中的. <div> <label>我是中国人</label> <input ...