javascript之-深入事件机制
链接:https://zhuanlan.zhihu.com/p/24620643
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1.1 事件绑定的方式
原生js的事件绑定方式有几种?想必有很多朋友说3种! 目前,在本人目前的研究中,只有两种半!两种半?还有半种的?且听我道来。
估计大家所认为的三种大概是如下三种:
// 第一种:直接绑定在dom上
<div onclick="fun();">click</div>
// 第二种,使用onclick
document.getElementById("xxx").onclick = function(){
};
// 第三种:使用推荐的标准模式
document.getElementById("xxx").addEventListener("click",function(e){
});
确实,这种方式是在网上搜到的最多的三种方式,但是这里有一个坑,就是当你同时使用三个的时候,第二个会把第一个给覆盖掉,也就是说第一种和第二种是属于同一个方式,只是写法不同,我们可以写一个demo为证:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<button id="btn1" onclick="fun1();">btn</button>
</body>
<script type="text/javascript">
function fun1(){
console.log("111");
}
var btn = document.getElementById("btn1");
btn.onclick = function(){
console.log("222");
}
btn.addEventListener("click",function(){
console.log("333");
})
</script>
</html>

看过我的另一篇博客 深入认识Document 的童鞋应该知道 onclick 是属于Elenent上的一个属性。所谓属性就是指只有一个,重复赋值会覆盖上一次的。但是addEventListener不会,这个方法会绑定多个事件程序,依次执行。
那么那剩下的半种方式到底是什么呢? 我就直接上代码了,毕竟程序猿是一种理解代码能力高于理解文字能力的动物:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<a id="btn1" onclick="fun1();" href="javascript:fun2();">btn</a>
</body>
<script type="text/javascript">
function fun1(){
console.log("111");
}
function fun2(){
console.log("222");
}
var btn = document.getElementById("btn1");
btn.addEventListener("click",function(){
console.log("333");
});
</script>
</html>

这下就解释清楚了,为啥是半种,因为使用场景很局限,很多标签用不了。这个时候细心的你可能发现了,这里的顺序也预期的不一样,对 这就是下一个话题了,js事件的执行顺序。
1.2 事件的执行顺序
demo代码就不写了,代码太多,感兴趣的可以直接复制上面你的进行修改,我就说下我得出的结论,
- a标签的href中的代码总是最后执行,最低的优先级。
- 无论是 onclick 还是 addEventListener 的执行顺序是按照 绑定的顺序在执行,就是先绑定的就先执行。
- 如果 onclick 事件被重复绑定,则以最后一次的绑定所在的顺序为准。
- 如果在DOM中直接使用onclick ,并且没有覆盖,则onclick的绑定是早于 addEventListener 的。
- 如果绑定多个 addEventListener 事件,在任意一个事件中 stopPropagation(); 都会阻止事件的冒泡,但不会阻止后续事件的执行。
1.3 详解事件对象
老规矩,还是先上代码,先看代码和效果图:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<button id="btn1">btn</button>
</body>
<script type="text/javascript">
var btn = document.getElementById("btn1");
btn.addEventListener("click",function(event){
console.log(event);
});
</script>
</html>
这时控制台打印了一个 MouseEvent 对象,这个稍微解释一点:
- clientX、clientY;layerX、layerY;offsetX、offsetY;pageX、pageY;screenX、screenY...... 等等这些都是事件触发的时候的一些相对坐标,有相对屏幕的、相对浏览器的、相对浏览器的、相对父元素、相对当前元素的,这里不多讲,可以自行摆渡。
- altKey、ctrlKey、shiftKey、metaKey:他们都是返回布尔值,分别表示 按住 alt键、ctrl键、shift键、win键,最后一个meta是windows下的win键,就是位于键盘左下角ctrl和alt之间的那个有windows标志的键,但是在mac上我没有测试,目前这个还没定论,希望有mac机器的同学可以测试一下试试。
- type:表示事件类型,这里当然是点击了。
- target:表示事件的触发源,经常在事件冒泡的时候使用,就是使用 event.target 来判断的。
- timeStamp: 从事件绑定完成到此次事件触发的时间,毫秒单位。
- path: 事件的冒泡顺序,表示事件是从哪里触发到那个地方结束(这个属性有兼容性问题,我在firefox中没找到这个属性)。
- 其他的属性就不用一个一个说了,有兴趣的可以仔细翻阅文档。(文章的最后面有地址)
这个时候有的同学可能会问了, 我平时为了阻止事件冒泡和默认事件使用过 stopPropagation和preventDefault方法,这里怎么没有呢?
这个问题问的好,原因是 topPropagation和preventDefault 是Event的方法,而 MouseEvent 是间接的继承了 Event 之后 就可以用这个方法了,那么他是在哪里继承的呢?
我们直接展开浏览器控制台的 MouseEvent 的__proto__ 属性,拉到最底部,发现他还有一个 __proto__ 属性,这个__proto__ 属性的类型是 UIEvent,在继续展开,UIEvent 的 __proto__ 是Event,Event里面就有了这两个方法,熟悉js原型链的同学应该都知道这个。
说白了 就是 MouseEvent 继承了 UIEvent,UIEvent 继承了 Event, Event 继承了 Object。 (这个原型链展开太长了 ,我就不截图了,童鞋们自己测试)
这下,你对事件是不是又有了一个全新的认识。
(文章为原创,转载请注明出处)
javascript之-深入事件机制的更多相关文章
- JavaScript 详说事件机制之冒泡、捕获、传播、委托
DOM事件流(event flow )存在三个阶段:事件捕获阶段.处于目标阶段.事件冒泡阶段. 事件捕获(event capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会 ...
- javascript 中的事件机制
1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...
- 【初窥javascript奥秘之事件机制】论“点透”与“鬼点击”
前言 最近好好的研究了一番移动设备的点击响应速度,期间不断的被自己坑,最后搞得焦头烂额,就是现在可能还有一些问题,但是过程中感觉自己成长不少, 最后居然感觉对javascript事件机制有了更好的认识 ...
- jQuery中的事件机制深入浅出
昨天呢,我们大家一起分享了jQuery中的样式选择器,那么今天我们就来看一下jQuery中的事件机制,其实,jQuery中的事件机制与JavaScript中的事件机制区别是不大的,只是,JavaScr ...
- JavaScript(1)---绑定事件、解除绑定事件
JavaScript(1)---绑定事件.解除绑定事件 一.事件概述 1.事件的几个概念 · 事件 指的是文档或者浏览器窗口中发生的一些特定交互瞬间.我们可以通过侦听器(或者处理程序)来预定事件,以便 ...
- 【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容)
前言 这篇博客有点长,如果你是高手请您读一读,能对其中的一些误点提出来,以免我误人子弟,并且帮助我提高 如果你是javascript菜鸟,建议您好好读一读,真的理解下来会有不一样的收获 在下才疏学浅, ...
- [解惑]JavaScript事件机制
群里童鞋问到关于事件传播的一个问题:“事件捕获的时候,阻止冒泡,事件到达目标之后,还会冒泡吗?”. 初学 JS 的童鞋经常会有诸多疑问,我在很多 QQ 群也混了好几年了,耳濡目染也也收获了不少,以后会 ...
- Javascript事件机制兼容性解决方案
本文的解决方案可以用于Javascript native对象和宿主对象(dom元素),通过以下的方式来绑定和触发事件: 或者 var input = document.getElementsByTag ...
- 【探讨】javascript事件机制底层实现原理
前言 又到了扯淡时间了,我最近在思考javascript事件机制底层的实现,但是暂时没有勇气去看chrome源码,所以今天我来猜测一把 我们今天来猜一猜,探讨探讨,javascript底层事件机制是如 ...
随机推荐
- mysql:添加索引
ALTER TABLE tb_user_type ADD INDEX user_type_index3 (report_type_id) ALTER TABLE tb_user_type ADD IN ...
- C# Form.Close 的释放问题
今天使用From窗口Close后,发现From的资源还存在,并没有释放资源,只有在程序关闭的时候才去释放. Form1:button按钮 private void button1_Click(obje ...
- SQLServer数据库中创建临时表
IF object_id('tempdb..#jimmy') is not NULL BEGIN DROP TABLE #jimmy; END IF object_id('tempdb..#jimmy ...
- Java中的equals和hashCode方法
本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...
- 在 Mac OS 上创建并运行 ASP.NET Core 1.0 网站
var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...
- 黑马程序员_Java基础:IO流总结
------- android培训.java培训.期待与您交流! ---------- IO流在是java中非常重要,也是应用非常频繁的一种技术.初学者要是能把IO技术的学透,java基础也就能更加牢 ...
- 总有一项适合你:联想 Miix2 8寸版触摸屏失灵的各项解决方案
今天试着自己拆开后盖重新拆了一下排线,果然这个方法才是王道.在搜索攻略的时候看到了下面的帖子,觉得总结的不错,特此转载过来: 白色石头 2015-05-22 10:07● 使用评测 总有一 ...
- 我对C#的理解
C#里面所有东西都可以看作对象.接口,类,枚举等等. 类是最常用的,可以继承别的接口,类等,就会自动拥有别人的功能. 接口是类的概要.给别人看的协议,好像一个人对外做出的承诺. 抽象类是实现了部分承诺 ...
- [UCSD白板题] Points and Segments
Problem Introduction The goal in this problem is given a set of segments on a line and a set of poin ...
- Java中区别.toString() ,(String),valueOf()方法
在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object.toString(),(String)要转换的对象,St ...