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

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

我之前一直以为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. Oracle客户端工具安装

    Oracle简易客户端登录工具安装 @[Database|Oracle|客户端工具] [TOC] 引言 Oracle服务的安装是一件的繁琐的事情,我们往往喜欢在本地不安装oracle数据库的方式来访问 ...

  2. git全部使用步骤

    今天要讲的内容:项目管理和工具 Git:版本控制系统 Less:动态的css语言,提高编写CSS的效率 Gulp:项目自动构建工具,对html,css,js,image进行压缩,合并等操作. 一.什么 ...

  3. 【Zookeeper】源码分析之网络通信(三)

    一.前言 前面已经学习了NIOServerCnxn,接着继续学习NettyServerCnxn. 二.NettyServerCnxn源码分析 2.1 类的继承关系 public class Netty ...

  4. mybatis系列笔记(2)---mapper代理方法

    mapper代理方法 在我们在写MVC设计的时候,都会写dao层和daoimp实现层,但假如我们使用mapper代理的方法,我们就可以不用先daoimp实现类 当然这得需要遵守一些相应的规则: (1) ...

  5. 隐马尔可夫模型(HMM)攻略

    隐马尔可夫模型 (Hidden Markov Model,HMM) 最初由 L. E. Baum 和其它一些学者发表在一系列的统计学论文中,随后在语言识别,自然语言处理以及生物信息等领域体现了很大的价 ...

  6. 【Unity编程】Unity中的欧拉旋转

    欧拉角的定义 在写这篇博客之前,我搜索了网上很多关于欧拉角的定义,发现大部分引用自维基百科的定义,我这里也引述一下: 维基百科定义 莱昂哈德·欧拉用欧拉角来描述刚体在三维欧几里得空间的取向.对于任何参 ...

  7. BOM基础(三)

    在我之前关于DOM的文章里,其实已经有提到过事件的概念.在讲事件之前,首先要知道的就是javascript是由事件驱动的.什么叫事件驱动呢?打个比方,比如我们在页面中点击一个按钮,才会跳出一个窗口或者 ...

  8. python 中如何导入一个自己创建的模块

    导入模块的语句的三种方法: 1.import module 2.from module import name1,[name2,name3....] 3.from module import * 先看 ...

  9. freemodbus移植讲解 ZZ

    一   为什么要移植Freemodbus 为什么要移植Freemodbus,这个问题需要从两个方面来回答.第一,modbus是一个非常好的应用层协议,它很简洁也相对完善.对于还没有接触过modbus的 ...

  10. mac下安装nginx问题解决

    需要在mac上安装nginx,按照下面的博客链接一步步安装,但是碰到了些问题.下面写一下我的解决方式. (http://stevendu.iteye.com/blog/1535466) 1. 安装PC ...