javascript之-深入事件机制
2016-12-29 23:25
309 查看
作者:yuyuyu
链接:https://zhuanlan.zhihu.com/p/24620643
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
估计大家所认为的三种大概是如下三种:
确实,这种方式是在网上搜到的最多的三种方式,但是这里有一个坑,就是当你同时使用三个的时候,第二个会把第一个给覆盖掉,也就是说第一种和第二种是属于同一个方式,只是写法不同,我们可以写一个demo为证:
看过我的另一篇博客 深入认识Document 的童鞋应该知道 onclick 是属于Elenent上的一个属性。所谓属性就是指只有一个,重复赋值会覆盖上一次的。但是addEventListener不会,这个方法会绑定多个事件程序,依次执行。
那么那剩下的半种方式到底是什么呢? 我就直接上代码了,毕竟程序猿是一种理解代码能力高于理解文字能力的动物:
这下就解释清楚了,为啥是半种,因为使用场景很局限,很多标签用不了。这个时候细心的你可能发现了,这里的顺序也预期的不一样,对 这就是下一个话题了,js事件的执行顺序。
a标签的href中的代码总是最后执行,最低的优先级。
无论是 onclick 还是 addEventListener 的执行顺序是按照 绑定的顺序在执行,就是先绑定的就先执行。
如果 onclick 事件被重复绑定,则以最后一次的绑定所在的顺序为准。
如果在DOM中直接使用onclick ,并且没有覆盖,则onclick的绑定是早于 addEventListener 的。
如果绑定多个 addEventListener 事件,在任意一个事件中 stopPropagation(); 都会阻止事件的冒泡,但不会阻止后续事件的执行。
这时控制台打印了一个 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。 (这个原型链展开太长了 ,我就不截图了,童鞋们自己测试)
这下,你对事件是不是又有了一个全新的认识。
MouseEvent 事件文档地址
(文章为原创,转载请注明出处)
链接: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。 (这个原型链展开太长了 ,我就不截图了,童鞋们自己测试)
这下,你对事件是不是又有了一个全新的认识。
MouseEvent 事件文档地址
(文章为原创,转载请注明出处)
相关文章推荐
- 韩顺平 javascript教学视频_学习笔记23_js事件驱动机制深入理解_js常用事件_js版计算器
- 深入理解JavaScript事件循环机制
- javascript中的事件捕获机制,深入理解并区别IE和DOM中的事件模型
- javascript之-深入事件机制
- 【JavaScript 学习--12】JS深入理解调用栈,事件循环机制,回调队列
- 深入研究JavaScript的事件机制
- javascript事件捕获机制【深入分析IE和DOM中的事件模型】
- 深入研究JavaScript的事件机制
- javascript事件机制了解与深入
- JavaScript的事件机制event对象
- JavaScript是否可实现多线程 —- 深入理解JavaScript定时机制
- Javascript事件注册机制--同时支持三种事件模型的javascript(转)
- 深入理解JAVA事件机制
- 深入理解JAVA事件机制
- 深入分析J2ME平台MIDP高级事件处理机制
- 【BCB 原创】深入 分析 C++Builder 6 的鼠标 单击 双击 事件 关键词: 单击 双击 实现机制
- JavaScript中external与active host之间的事件调用机制
- 深入理解JavaScript中的事件
- JavaScript的事件处理机制
- 深入探索面向对象事件(Delegate)机制