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 = xxx这种赋值写法绑定事件的原理是什么?的更多相关文章
- 面试时被问到js的绑定事件,我居然不知道怎么回答。回来查了下,做个笔记
事件绑定是几种方法 以下为例: <button id='btn'>click me</button> function Btn(){ alert('click'); } 1.直 ...
- JavaScript中给onclick绑定事件后return false遇到的问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js绑定事件方法:addEventListener与attachEvent的不同浏览器的兼容性写法
js的事件绑定方法中,ie仅仅支持attachEvent,而FF和Chrome仅仅支持addEventListener,所以就必须为这两个方法做兼容处理,原理是先推断attachEvent仅仅否为真( ...
- 原生JS事件绑定方法以及jQuery绑定事件方法bind、live、on、delegate的区别
一.原生JS事件绑定方法: 1.通过HTML属性进行事件处理函数的绑定如: <a href="#" onclick="f()"> 2.通过JavaS ...
- JQuery在循环中绑定事件的问题详解
JQuery在循环中绑定事件的问题详解 有个页面上需要N个DOM,每个DOM里面的元素ID都要以数字结尾,比如说 ? 1 2 3 <input type="text" nam ...
- jQuery delegate方法实现Ajax请求绑定事件不丢失
给元素绑定click事件后 ,遇到一个问题:当执行一些ajax请求,再次调用此页面,里面的这个click事件就失效了 比如说:我的分页是一个ajax请求 但我点下一页时 后生成的元素a就没有了clic ...
- JavaScript绑定事件的方法[3种]
在JavaScript中,有三种常用的绑定事件的方法: 在DOM元素中直接绑定: 在JavaScript代码中绑定: 绑定事件监听函数. 一. 在DOM元素中直接绑定 这里的DOM元素,可以理解为HT ...
- Xamarin.Android中使用android:onClick="xxx"属性
原文:Xamarin.Android中使用android:onClick="xxx"属性 在原生Android开发中,为一个View增加点击事件,有三种方式: 1.使用匿名对象 ( ...
- dom元素循环绑定事件的技巧
以前总觉得自己写的代码不太规范,尤其是写原生的时候.举个例子: 要为页面上所有".a"的元素绑定事件,当然了用jquery很方便:$('.a').bind("click& ...
随机推荐
- List实现行转列的通用方案
最近在做报表统计方面的需求,涉及到行转列报表.根据以往经验使用SQL可以比较容易完成,这次决定挑战一下直接通过代码方式完成行转列.期间遇到几个问题和用到的新知识这里整理记录一下. 阅读目录 问题介绍 ...
- 数据库:oracle,MySQL,SqlServer 安装资源分享
1. oracle 11g: 链接:http://pan.baidu.com/s/1bppaqR1 密码:http 2. mysql 链接:http://pan.baidu.com/s/1jH8O ...
- Handlebars模板引擎之进阶
取得索引 我想取得索引作为序号这个是常用的.在handlebars也是存在的. 就是使用 @index 来获取索引 {{#each this}} <tr> <td>{{ @in ...
- org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.entity.annotations.House.district in
org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.entity. ...
- 2017-3-2 C#链接数据库实现登陆
只是链接一个数据库就有好多的知识:) 实际操作下来,主要是两种登陆方式: 1.Windows的身份验证: 2.Sql Sever的身份验证: 两种的方法不同,但是主要是通过复制创建数据库的字符串来链接 ...
- Ceph osd启动报错osd init failed (36) File name too long
在Ceph的osd节点上,启动osd进程失败,查看其日志/var/log/ceph/ceph-osd.{osd-index}.log日志,报错如下: 2017-02-14 16:26:13.55853 ...
- webpack-react之webpack篇(http://www.jianshu.com/p/794d573d2c53)
构建一个小项目——FlyBird,学习webpack和react.(本文成文于2017/2/25) 从webpack开始本篇从零开始,详细记录webpack的各个方面.文章中将会放入很多链接以便扩展, ...
- CSS知识点汇总 (全是干货O(∩_∩)O~ )
一.CSS选择器 [选择器的命名规则] 1.只能有字母数字下划线组成,不能有其他任何特殊字符 2.开头不能是数字 [通用选择器]1.写法:*{}2.作用:选中页面中的所有标签(大范围修改)3.优先级: ...
- Struts2学习笔记⑧
今天是Struts2学习笔记的最后一篇文章了.用什么做结尾呢,这两天其实还学了很多东西,没有记录下,今天就查漏补缺一下. 文件上传与下载.FreeMarker以及昨天没做完的例子 文件上传与下载 文件 ...
- Java Stream API入门篇
本文github地址 你可能还没意识到Java对函数式编程的重视程度,看看Java 8加入函数式编程扩充多少类就清楚了.Java 8之所以费这么大功夫引入函数式编程,原因有二: 代码简洁,函数式编程写 ...