Javascript事件的捕获方式和冒泡方式详解

目录
  • 一、事件处理模型
    • 1、事件冒泡
      • (1)给三个div元素绑定事件
      • (2)运行结果:
    • 2、事件捕获
      • (1)给三个div元素绑定事件
      • (2)运行结果:
  • 二、阻止事件冒泡
    • (1)w3c标准 event.stopPropagation();但ie9以下版本不支持
    • (2)ie独有:event.cancelBubble = true;
    • (3)合并取消:return false
  • 总结

一、事件处理模型

事件冒泡、捕获:事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。

<div id="d1">
        <div id="d2">
            <div id="d3"></div>
        </div>
</div>

给出的具有嵌套关系的三个div,给三个元素注册相同的事件时,它们的触发顺序时怎样呢?

1、事件冒泡

微软提出了名为事件冒泡的事件流。结构上(非视觉上)嵌套关系的元素,会存在冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)

针对上面的例子,如果用冒泡方式,触发顺序应该时:d3——>d2——>d1,那么我们来验证一下:

(1)给三个div元素绑定事件

//1.获取元素
var d1 = document.querySelector('#d1')
var d2 = document.querySelector('#d2')
var d3 = document.querySelector('#d3')
//2、绑定事件
d1.onclick = function(){
     console.log(this.id)
  }
d2.onclick = function(){
      console.log(this.id)
  }
d3.onclick = function(){
      console.log(this.id)
   }

(2)运行结果:

单击红色区域:

单击紫色区域:

单击绿色区域: 

以上就是事件冒泡啦! 

2、事件捕获

结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)(ie没有捕获事件)

针对上面的例子,如果用冒泡方式,触发顺序应该时:d1——>d2——>d3,那么我们来验证一下:

(1)给三个div元素绑定事件

//1.获取元素
var d1 = document.querySelector('#d1')
var d2 = document.querySelector('#d2')
var d3 = document.querySelector('#d3')
//2、绑定事件
d1.onclick = function(){
     console.log(this.id)
  }
d2.onclick = function(){
      console.log(this.id)
  }
d3.onclick = function(){
      console.log(this.id)
   }

(2)运行结果:

单击红色区域:

 

单击紫色区域:

单击绿色区域:

事件捕获get!!! 

注意:

  • 触发顺序 :先捕获,后冒泡
  • focus,blur,change,submit,reset,select等事件不冒泡

二、阻止事件冒泡

(1)w3c标准 event.stopPropagation();但ie9以下版本不支持

//1.获取元素
var d1 = document.querySelector('#d1')
var d2 = document.querySelector('#d2')
var d3 = document.querySelector('#d3')
//2、绑定事件
d1.onclick = function(){
     console.log(this.id)
  }
d2.onclick = function(){
      console.log(this.id)
  }
d3.onclick = function(e){
      e.stopPropagation();
      console.log(this.id)
   }

会发现单击绿色区域时 ,没有依次触发外部的事件,事件冒泡被阻止:

(2)ie独有:event.cancelBubble = true;

//1.获取元素
var d1 = document.querySelector('#d1')
var d2 = document.querySelector('#d2')
var d3 = document.querySelector('#d3')
//2、绑定事件
d1.onclick = function(){
     console.log(this.id)
  }
d2.onclick = function(){
      console.log(this.id)
  }
d3.onclick = function(e){
      e.cancelBubble = true;
      console.log(this.id)
   }

结果同(1)。

(3)合并取消:return false

在javascript的return false只会阻止默认行为,而是用jQuery的话则既阻止默认行为又防止对象冒泡。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 深入了解最常用的JavaScript 事件

    目录 JavaScript 事件: 常用的事件: 事件操作 总结 JavaScript 事件: 事件指的就是当某些组件执行了某些操作后,会触发某些代码的执行. 常用的事件: 属性 触发时机 onabort 图像加载被中断 onblur 元素失去焦点 onchange 用户改变域的内容 onclick 鼠标点击某个对象 ondblclick 鼠标双击某个对象 onerror 当加载文档或图像时发生某个错误 onfocus 元素获得焦点 onkeydown 某个键盘的键被按下 onkeypress

  • js事件委托详解

    1.每个函数都是对象,占用内存.内存中的对象越多,性能越差.解决事件处理过多问题的办法是事件委托. 2.事件委托冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件. 实例 <ul id="myLinks"> <li id="myLi1">text1</li> <li id="myLi2">text2</li> <li id="myLi3">text

  • JavaScript 关于事件循环机制的刨析

    目录 前言: 一.事件循环和任务队列产生的原因: 二.事件循环机制: 三.任务队列: 3.1 任务队列的类型: 3.2 两者区别: 3.3 更细致的事件循环过程 四.强大的异步专家 process.nextTick() 4.1 process.nextTick()在何时调用? 前言: 这次主要整理一下自己对 Js事件循环机制,同步,异步任务,宏任务,微任务的理解,大概率暂时还有些偏差或者错误.如果有,十分欢迎各位纠正我的错误! 一.事件循环和任务队列产生的原因: 首先,JS是单线程,这样设计也是

  • JavaScript之事件循环案例讲解

    js中的事件循环 因为JavaScript是单线程的,同一事件只能执行一种方法,所以会将程序中的方法加入到执行栈中按照后进先出的顺序依次执行,当遇见异步任务时不会被阻塞,而是将任务放入事件队列中,继续执行执行栈中的同步代码,等当前执行栈中的所有任务都执行完毕则查找事件队列中的任务,并把任务的回调函数放入执行栈中,执行其中的同步代码,如此反复形成的循环被称为事件循环. node.js node.js特点 事件驱动 从上向下执行代码,当遇到需要回调的地方就加入到事件队列中,主线程运行完就去执行事件队

  • JavaScript 事件捕获冒泡与捕获详情

    目录 一.事件流 1.概念 2.DOM事件流 二.事件委托 1.事件委托的优点 2.事件委托的使用 三.禁止事件冒泡与捕获 四.参考文献 一.事件流 JavaScript中,事件流指的是DOM事件流. 1.概念 事件的传播过程即DOM事件流. 事件对象在 DOM 中的传播过程,被称为"事件流". 举个例子:开电脑这个事,首先你是不是得先找到你的电脑,然后找到你的开机键,最后用手按下开机键.完成开电脑这个事件.这整个流程叫做事件流. 2.DOM事件流 DOM事件,也是有一个流程的.从事件

  • 浅析js中事件冒泡与事件捕获

    目录 01-事件冒泡 1.1-事件冒泡介绍 1.2-事件冒泡利用(事件委托) 1.3-事件冒泡影响 与 阻止事件冒泡 02-事件捕获 1.1-事件捕获介绍 1.2-事件三个阶段 01-事件冒泡 1.1-事件冒泡介绍 本小节知识点:介绍什么是事件冒泡 事件冒泡:如果一个元素的事件被触发,那么他的所有父级元素的同名事件也会被依次触发 元素->父元素->body->html->document->window 事件冒泡一直存在,只不过以前我们没有给父级元素加同名事件 <!DO

  • vc控制台程序关闭事件时的处理方式及注意点详解

    百度可以找到很多关于这个问题解决的方法 关键控制台API函数:SetConsoleCtrlHandler 在支持C++ 11以上的编译器中,你可以这么做. SetConsoleCtrlHandler([](DWORD fdwctrltype)->BOOL { if (fdwctrltype == CTRL_CLOSE_EVENT) { // 你的善后代码... return TRUE; } return FALSE; }, TRUE); 最初这么做是很舒服的,但之后发现了问题: Windows控

  • vue父子组件动态传值的几种方式及注意问题详解

    1.vue父组件向子组件动态传值的两种方法 在一些项目需求中需要父组件向子组件动态传值,比如我这里的需求是,父组件动态通过axios获取返回的图片url数组然后传给子组件,上传图片的子组件拿到该数组后进行遍历并展示图片,因为有时候获取到的会是空,所以这里要考虑到动态获取. 方法有两种, vue父组件向子组件动态传值方法一: props传值,这里注意一个问题,传过来的值需要用watch监听并赋值,否则这里获取到的是空数组 父组件: <uploadImg :width="200" :

  • ASP.NET页面之间传值的方式之Application实例详解

    Application Application变量在整个应用程序生命周期中都是有效的,类似于使用全局变量一样,所以可以在不同页面中对它进行存取.它和Session变量的区别在于,前者是所有的用户共用的全局变量,后者是各个用户独有的全局变量. 举例来解释: 网站访问的计数器变量一般采用Application变量,多个请求访问时共享这一个变量,均可对它进行操作,该变量可以被整个应用程序的各个页面直接使用. 用户登陆的帐号名一般采用Session变量,多个请求访问时有各自的Session变量,只能对自

  • Java中map遍历方式的选择问题详解

    1. 阐述 对于Java中Map的遍历方式,很多文章都推荐使用entrySet,认为其比keySet的效率高很多.理由是:entrySet方法一次拿到所有key和value的集合:而keySet拿到的只是key的集合,针对每个key,都要去Map中额外查找一次value,从而降低了总体效率.那么实际情况如何呢? 为了解遍历性能的真实差距,包括在遍历key+value.遍历key.遍历value等不同场景下的差异,我试着进行了一些对比测试. 2. 对比测试 一开始只进行了简单的测试,但结果却表明k

  • 关于函数调用方式__stdcall和__cdecl详解

    关于函数调用方式__stdcall和__cdecl详解 __stdcall __cdecl 两者的相同点与不同点 实例 __stdcall __stdcall的全称是standard call.是C++的标准调用方式. 函数参数的入栈顺序为从右到左入栈.函数返回时使用retn x指令,其中x为调整堆栈的字节数.这种方式叫做自动清栈.即被调用的函数的参数个数是固定的,调用者必须严格按照定义传递参数,一个不多,一个不少. __cdecl __cdecl的全称是C Declaration,即C语言默认

  • Spring AOP拦截-三种方式实现自动代理详解

    这里的自动代理,我讲的是自动代理bean对象,其实就是在xml中让我们不用配置代理工厂,也就是不用配置class为org.springframework.aop.framework.ProxyFactoryBean的bean. 总结了一下自己目前所学的知识. 发现有三种方式实现自动代理 用Spring一个自动代理类DefaultAdvisorAutoProxyCreator: <bean class="org.springframework.aop.framework.autoproxy.

  • Volley源码之使用方式和使用场景详解

    概述 Volley是Google在2013年推出的一个网络库,用于解决复杂网络环境下网络请求问题.刚推出的时候是非常火的,现在该项目的变动已经很少了.项目库地址为https://android.googlesource.com/platform/frameworks/volley 通过提交历史可以看到,最后一次修改距离今天已经有一段时间了.而volley包的release版本也已经很久没有更新了. author JeffDavidson<jpd@google.com> SunMar1316:3

  • 对Python中创建进程的两种方式以及进程池详解

    在Python中创建进程有两种方式,第一种是: from multiprocessing import Process import time def test(): while True: print('---test---') time.sleep(1) if __name__ == '__main__': p=Process(target=test) p.start() while True: print('---main---') time.sleep(1) 上面这段代码是在window

  • JS代码简洁方式之函数方法详解

    函数的参数越少越好 有一个准则是:如果你的函数参数超过两个,就应该改为对象传入. 这样做是合理的,因为当函数参数超过两个时,参数顺序开始变得难以记忆,而且容易出现一种很尴尬的情况:比如我只需要传入第三个参数,因为其自身顺序的原因,不得不补齐前两个根本用不上的参数,以让它顺利排在第三位. // bad const createArticle = (title, author, date, content) => { } createArticle('震惊,一男子竟偷偷干这事', 'zhangnan

  • Mybatis注解方式操作Oracle数据库详解

    1.新增多行数据 @Insert({"<script>insert all " + "<foreach collection=\"list\" index=\"index\" item=\"item\" open=\"\" separator=\"\" close=\"\">" + " into s_user (u

随机推荐