JS事件流机制

  一个完整的JS事件流是从window开始,最后回到window的一个过程,事件流被分为三个阶段:

  (1~5)捕获过程、(5~6)目标过程、(6~10)冒泡过程。

  通过addEventListener可以监听冒泡阶段的事件,如果第三个参数指定为true,则监听的是捕获阶段的事件。低版本IE(6,7,8)不支持捕获阶段的事件监听,只能用attachEven来监听冒泡阶段事件。这不意味着低版本IE没有事件捕获,其实有,只不过没办法去监听而已

attachEvent和addEventListener的对比

  1. 两者都可以为一个元素添加多个事件监听,不会出现覆盖问题
  2. 前者回调函数中this指向window,后者回调函数中this指向当前元素
  3. 前者监听的是事件冒泡,而后者通过第三个参数可以指定为冒泡(默认false)或者捕获(true)
  4. 对于阻止事件冒泡,前者调用e.cancelBubble=true,而后者调用e.stopPropagation()
  5. 事件名不一样:前者“onclick”,而后者“click”
  6. 前者支持IE10及以下(IE11以及以上使用的话,会提示没有这个方法),而后者IE9及以上和非IE浏览器

阻止默认行为

标准写法:

function cancelHandler(event){
event=event||window.event;//兼容IE //取消事件相关的默认行为
if(event.preventDefault) //标准技术
event.preventDefault();
if(event.returnValue) //兼容IE9之前的IE
event.returnValue=false;
return false; //用于处理使用对象属性注册的处理程序
}

  因为IE6,7,8回调函数的没有传入参数,而是要通过window.event来获取事件对象;而且ff中没有全局的window.event事件对象,所以兼容的写法就是 event || window.event

  dom0级事件(onclick=xxx)中,使用e.returnValue = false【IE9以上不支持】 、e.preventDefault()【IE6,7,8不支持】或者return false【主要用在dom0级事件中,如onclick=xx】都有效

  dom2级事件(addEventListener)中,使用return false无效

  attachEvent中使用e.preventDefault()无效

ps:阻止a标签的默认行为

事件委托

  利用事件冒泡,把对多个子元素的事件监听,转换为对一个父元素的事件监听,可以提升效率(减少内存对象)。其实利用捕获或者冒泡实现都可以,只不过主流浏览器都支持事件冒泡,所以从兼容性的角度来还是选用冒泡。

<ul id="color-list">
<li>red</li>
<li>yellow</li>
<li>blue</li>
<li>green</li>
<li>black</li>
<li>white</li>
</ul> (function(){
var color_list = document.getElementById('color-list');
color_list.addEventListener('click',showColor,false);
function showColor(e){
var x = e.target;
if(x.nodeName.toLowerCase() === 'li'){
alert('The color is ' + x.innerHTML);
}
}
})();

  以上使用委托除了节省了内存外,还有另外一个好处,当动态添加了一个子元素,不需要为这个子元素绑定事件,更加便捷。

事件目标

evt中对于事件对象有三个属性:currentTarget、target和srcElement

currentTarget:代表当前节点,一般与this指向相同。(attachEvent中this指向window)

target和srcElement:实际发生事件的dom对象。ff不支持srcElement,所以兼容的写法是: var target = e.target || e.srcElement

事件其他属性

bubbles:代表当前事件是否会冒泡,除了focus、blur和scroll三种事件不会冒泡之外,其他类型的事件改属性都为true

cancelBubble:默认为false,设置为true时,用于阻止冒泡,对捕获阶段无效,全浏览器支持,但不是标准写法,应尽量使用stopPropagation

stopPropagation() :阻止事件在事件流(先捕获后冒泡)中的传播。一种情况例外,如果在A上捕获事件,里面执行stopPropagation,则A的冒泡回调也会执行:

<div id="a">
123
<div id="b">
456
<div id="c">
789
</div>
</div>
</div>
<script>
var a = document.querySelector("#a");
var b = document.querySelector("#b");
var c = document.querySelector("#c"); a.addEventListener('click',(e)=>{
console.log("a") },true) b.addEventListener('click',(e)=>{
console.log("b")
e.stopPropagation()
},true) c.addEventListener('click',(e)=>{
console.log("c")
},true) a.addEventListener('click',(e)=>{
console.log("2 a")
}) b.addEventListener('click',(e)=>{
console.log("2 b")
}) c.addEventListener('click',(e)=>{
console.log("2 c")
},true)
</script>
点击456,输出 a b 2b。

stopImmediatePropagation():在阻止事件传播的基础上,同时阻止当前元素上对同一事件的其他回调函数的执行

总结低版本IE与其他浏览器的事件差异

  1. 获取事件对象的方式不同
  2. 取消默认行为的方式不同
  3. 可以检测控制的事件流不同

dom事件机制系列的更多相关文章

  1. 深入理解DOM事件机制系列第四篇——事件模拟

    × 目录 [1]引入 [2]模拟机制 [3]自定义事件 前面的话 事件是网页中某个特别的瞬间,经常由用户操作或通过其他浏览器功能来触发.但实际上,也可以使用javascript在任意时刻来触发特定的事 ...

  2. 深入理解DOM事件机制系列第三篇——事件对象

    × 目录 [1]获取 [2]事件类型 [3]事件目标[4]事件代理[5]事件冒泡[6]事件流[7]默认行为 前面的话 在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事 ...

  3. 深入理解DOM事件机制系列第二篇——事件处理程序

    × 目录 [1]HTML [2]DOM0级 [3]DOM2级[4]IE[5]总结 前面的话 事件处理程序又叫事件侦听器,实际上就是事件的绑定函数.事件发生时会执行函数中相应代码.事件处理程序有HTML ...

  4. 深入理解DOM事件机制系列第一篇——事件流

    × 目录 [1]历史 [2]事件冒泡 [3]事件捕获[4]事件流 前面的话 javascript操作CSS称为脚本化CSS,而javascript与HTML的交互是通过事件实现的.事件就是文档或浏览器 ...

  5. DOM事件机制进一步理解

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  6. DOM事件机制

    前言 本文主要介绍DOM事件级别.DOM事件模型.事件流.事件代理和Event对象常见的应用,希望对你们有些帮助和启发! 本文首发地址为GitHub博客,写文章不易,请多多支持与关注! 一.DOM事件 ...

  7. DOM事件机制(事件捕获和事件冒泡和事件委托)

    内容: 1.事件复习 2.事件冒泡与事件捕获 3.事件委托 1.事件复习 (1)事件 事件是用来处理响应的一个机制,这个响应可以来自于用户(点击, 鼠标移动, 滚动), 也可以来自于浏览器 下面的链接 ...

  8. DOM 事件机制&事件委托

    一.事件机制 事件是在编程时系统内发生的动作或者发生的事情,系统会在事件出现的时候触发某种信号并且会提供一个自动加载某种动作的机制(来自MDN).每个事件都有事件处理器(有时也叫事件监听器),也就是触 ...

  9. 系统学习DOM事件机制

    本文将从以下几个方面介绍DOM事件: 基本概念:DOM事件的级别 DOM事件模型,事件流 描述DOM事件捕获的具体流程 Event对象的常见应用 自定义事件 DOM事件的级别 //DOM0 eleme ...

随机推荐

  1. Yac - PHP扩展

    1:首先你要安装Git [root@localhost]# git clone https://github.com/laruence/yac 2:进入yac目录进行配置 [root@localhos ...

  2. 如何使用程序调用webApi接口

    如何使用程序调用webApi接口 在C#中,传统调用HTTP接口一般有两种办法: WebRequest/WebResponse组合的方法调用 WebClient类进行调用. 第一种方法抽象程度较低,使 ...

  3. Codeforces Round #547 (Div. 3) A.Game 23

    链接:https://codeforces.com/contest/1141/problem/A 题意: 给n和m,有两种操作:将n×2 或 n×3,求最少的乘法次数由n得到m. 不能得到时为-1. ...

  4. 牛客寒假6-D.美食

    链接:https://ac.nowcoder.com/acm/contest/332/D 题意: 小B喜欢美食. 现在有n个美食排成一排摆在小B的面前,依次编号为1..n,编号为i的食物大小为 a[i ...

  5. ubuntu dpkg命令总结

    dpkg是Debian系统的后台包管理器,类似RPM.也是Debian包管理系统的中流砥柱,负责安全卸载软件包,配置,以及维护已安装的软件包.由于ubuntu和Debian乃一脉相承,所以很多命令是不 ...

  6. tar打包压缩命令

    1. tar命令 用法: tar [选项...] [FILE]... GNU ‘tar’将许多文件一起保存至一个单独的磁带或磁盘归档,并能从归档中单独还原所需文件. 示例 tar -cf archiv ...

  7. 洛谷 P1873 砍树

    砍树 二分答案,难度较低. #include <iostream> #include <cstdio> #include <algorithm> using nam ...

  8. AFNetworking 一般用法

    AFNetworking是一个用于iOS.macOS.watchOS和tvOS的功能强大的网络库.它构建在基础URL加载系统之上,扩展了强大的高级网络抽象,并将其构建为Cocoa.它有一个模块化的架构 ...

  9. Oracle种常用性能监控SQL语句

    --Oracle常用性能监控SQL语句 --1 SELECT * FROM SYS.V_$SQLAREA WHERE DISK_READS > 100; --2 监控事例的等待 SELECT E ...

  10. explian使用介绍

    1).id列数字越大越先执行,如果说数字一样大,那么就从上往下依次执行,id列为null的就表是这是一个结果集,不需要使用它来进行查询. 2).select_type列常见的有:A:simple:表示 ...