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. 对单片机C语言的一些误用和总结

    在学习单片机的时候才真正知道C语言是什么它是来干什么的~但是C语言用到嵌入式只是它小小的一部分他的应用还有很多地方呢,呵呵我们这里就不讨论这个了.我们是不是在写程序的时候错误很多就算编译通过了也达不到 ...

  2. Log4j2 - java.lang.NoSuchMethodError: com.lmax.disruptor.dsl.Disruptor

    问题 项目使用了log4j2,由于使用了全局异步打印日志的方式,还需要引入disruptor的依赖,最后使用的log4j2和disruptor的版本依赖如下: <dependency> & ...

  3. PostgreSQL-13-缺失值处理

    -- 1.查看缺失值CREATE TABLE dnull AS SELECT * FROM data; -- 复制数据SELECT * FROM dnull WHERE 房屋编码 IS NULL OR ...

  4. AKOJ-1695-找素数

    题意: 给定区间L,R. 计算区间中素数个数. 2 <= L,R <= 2147483647, R-L <= 1000000. 思路: 素数区间筛 先筛(2-sqrt(r)). 再用 ...

  5. 532 K-diff Pairs in an Array 数组中差为K的数对

    详见:https://leetcode.com/problems/k-diff-pairs-in-an-array/description/ C++: class Solution { public: ...

  6. 114 Flatten Binary Tree to Linked List 二叉树转换链表

    给定一个二叉树,使用原地算法将它 “压扁” 成链表.示例:给出:         1        / \       2   5      / \   \     3   4   6压扁后变成如下: ...

  7. avalon使用体验

    最近在用avalon做项目,使用的感受是,它确实会比angualr学习成本更低,我不需要花很多时间去了解它的功能,没有指令.没有服务,花一个晚上看看API就差不多能着手用了.avalon的视图它提供了 ...

  8. spring security 5 There is no PasswordEncoder mapped for the id "null" 错误

    转载请注明出处 http://www.cnblogs.com/majianming/p/7923604.html 最近在学习spring security,但是在设置客户端密码时,一直出现了一下错误提 ...

  9. 我的NopCommerce之旅(5): 缓存

    一.基础介绍 1.什么是cache      Web缓存是指一个Web资源(如html页面,图片,js,数据等)存在于Web服务器和客户端(浏览器)之间的副本. 2.为什么要用cache      即 ...

  10. kafka系列二:多节点分布式集群搭建

    上一篇分享了单节点伪分布式集群搭建方法,本篇来分享一下多节点分布式集群搭建方法.多节点分布式集群结构如下图所示: 为了方便查阅,本篇将和上一篇一样从零开始一步一步进行集群搭建. 一.安装Jdk 具体安 ...