js事件冒泡

javascript的事件传播过程中,当事件在一个元素上出发之后,事件会逐级传播给先辈元素,直到document为止,有的浏览器可能到window为止,这就是事件冒泡现象。

<div id="col">
    <p>
        <a id="btn" href="#">button</a>
    </p>
</div>
<script>
let btnclick = document.getElementById('col');
btnclick.onclick=function(e){
    console.log('1');
};
<script>

执行结果,当点击a标签时,也可以在控制台输出1;但是a元素并没有绑定click事件,这就是由于事件冒泡的现象,事件逐级传播给先辈元素,点击a——p——div,然后就可以执行对应的div绑定的事件。

特别说明:并不是所有的事件都有冒泡现象,比如如下几个:blur事件 focus事件 load事件

js事件委托

事件委托又可以叫事件代理,事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

事件委托的益处:我们都知道,减少dom操作可以提高网页性能,当一个页面的父级元素和很多子级元素都需要操作同一件事件的时候,我们不可能每个元素都去给它绑定一个事件,看下面例子:

<ul id="getNum">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
let ptclick = document.getElementById('getNum');
let lilist = ptclick.querySelectorAll('li');
for(let i=0;i<lilist.length;i++){
lilist[i].index = i;
};
ptclick.onclick = function(e){
var e = e || window.event;
var target = e.target || e.srcElement;
console.log(e.target.index);
}; </script>

点击每个li元素都会打印对应的目标li的index值;

但是并不是所有的情况都适用于事件冒泡的,当出现父子级之间的注册事件不一致时,就不适用。关于事件委托更加详细的解释,查https://www.cnblogs.com/liugang-vip/p/5616484.html

每个例子都很详细的分析了。

js事件捕获

事件捕获恰好与事件冒泡相反,它从顶层祖先元素开始,直到事件触发元素。

DOM标准同时支持捕获事件模型和冒泡事件模型,但是,捕获事件模型先发生。两种事件流都会触发DOM中的所有对象,从document对象开始,也在document对象结束。

js事件捕获一般通过DOM2事件模型addEventListener来实现的:

target.addEventListener(type, listener, useCapture)

第三个参数默认设置为false,表示在冒泡阶段出发事件,设置为true时表示在捕获阶段触发,一般我们工作中似乎很少使用事件捕获。但还是要理解一下,面试过程中没少问过这类问题。

分析例子:

<div id="box">
<div id="middle">
<div id="inner"></div>
</div>
</div> <script> //事件捕获
window.onload=function(){
let box=document.getElementById("box");
let middle=document.getElementById("middle");
let inner=document.getElementById("inner");
box.addEventListener("click",function(){console.log("box")},true);
middle.addEventListener("click",function(){console.log("middle")},true);
inner.addEventListener("click",function(){console.log("inner")},true);
}
</script>

当点击inner绑定事件时,控制台会直接输出,box,middle,inner

js阻止事件冒泡

平时开发过程中,会用到大量的事件冒泡事件,但是可能我们在某个子级标签不需要传递事件给父级,这时候就需要阻止它事件的冒泡。

一般,使用stopPropagation来阻止事件的冒泡,IE中使用cancleBuble=true,stopPropagation也是事件对象(Event)的一个方法,作用是阻止目标元素的冒泡事件,但是会不阻止默认行为。

接上面事件冒泡的例子:

//阻止事件冒泡
let btna = document.getElementById('btn');
btna.onclick=function(e){
window.event? window.event.cancelBubble = true : e.stopPropagation();
};

此时,当点击a标签元素时,控制台就不会再打印出1;

阻止浏览器默认行为

开发过程中,总会出现各种浏览器的默认行为,这时候就需要阻止浏览器的默认行为,一般情况下,使用

preventDefault阻止浏览器的默认行为,在IE浏览器下,使用returnValue = false;

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

//阻止浏览器的默认行为
function stopDefault( e ) {
//一般情况下
if ( e && e.preventDefault )
e.preventDefault();
//IE中
else
window.event.returnValue = false;
return false;
}

理解js事件冒泡事件委托事件捕获的更多相关文章

  1. javascript 事件传播与事件冒泡,W3C事件模型

    说实话笔者在才工作的时候就听说了什么"事件冒泡",弄了很久才弄个大概,当时理解意思是子级dom元素和父级dom元素都绑定了相同类型的事件,这时如果子级事件触发了父级也会触发,然后这 ...

  2. jQuery里面的普通绑定事件和on委托事件

    以click事件为例: 普通绑定事件:$('.btn1').click(function(){}绑定 on绑定事件:$(document).on('click','.btn2',function(){ ...

  3. [已转移]js事件流之事件冒泡的应用----事件委托

    该文章已转移到博客:https://cynthia0329.github.io/ 什么是事件委托? 它还有一个名字叫事件代理. JavaScript高级程序设计上讲: 事件委托就是利用事件冒泡,只指定 ...

  4. vue中事件冒泡规则和事件捕获规则

    <div id="app"> <div @click="handleClickOne"> <p @click="hand ...

  5. js时间冒泡,阻止事件冒泡

    首先解释一下事件冒泡神什么, 在js中,假如在div中嵌套一个div 如 <style type="text/css"> #box1{width:500px;heigh ...

  6. vue.js阻止事件冒泡和默认事件

    首先我们来看原生JS取消事件冒泡方法: e.stopPropagation(); //非IE浏览器window.event.cancelBubble = true; //IE浏览器 原生JS阻止默认事 ...

  7. js阻止浏览器、元素的默认事件与js阻止事件冒泡、阻止事件流

    嵌套的div元素,如果父级和子元素都绑定了一些事件,那么在点击最内层子元素时可能会触发父级元素的事件,下面介绍一下js阻止默认事件与js阻止事件冒泡示例,大家参考使用吧   1. event.prev ...

  8. js事件冒泡、阻止事件冒泡以及阻止默认行为

    事件冒泡 当事件发生后,这个事件就要开始传播(从里到外或者从外向里).为什么要传播呢?因为事件源本身(可能)并没有处理事件的能力,即处理事件的函数(方法)并未绑定在该事件源上.例如我们点击一个按钮时, ...

  9. js阻止冒泡和默认事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. vue学习笔记(一)关于事件冒泡和键盘事件 以及与Angular的区别

    一.事件冒泡 方法一.使用event.cancelBubble = true来组织冒泡 <div @click="show2()"> <input type=&q ...

随机推荐

  1. Javascript中escape()、encodeURI()、encodeURIComponent()的区别

    JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decod ...

  2. 彻底关闭win10的自动更新,一定要坚持看到最后一页

    https://jingyan.baidu.com/article/9faa7231e7b78b473c28cbb6.html 是否好使我还在测试,不好使的话,再跟新 2018-05-20 今天电脑又 ...

  3. struts2用到的jar有那些

    struts2.0 lib/antlr-2.7.6.jarlib/struts2-core-2.0.14.jarlib/struts2-spring-plugin-2.0.14.jarlib/free ...

  4. MySQL之练习题5

    .将所有的课程的名称以及对应的任课老师姓名打印出来,如下: SELECT cname,tname FROM course INNER JOIN teacher WHERE course.teacher ...

  5. 2018.10.13 bzoj1070: [SCOI2007]修车(费用流)

    传送门 费用流经典题目. 自我感觉跟TheWindy′sThe Windy'sTheWindy′s很像. 利用费用提前计算的思想来建图就行了. 代码: #include<bits/stdc++. ...

  6. [K8S]污点调度

    如果不希望某个节点被调度可以使用以下命令进行设置  kubectl taint node master01 node-role.kubernetes.io/master="":No ...

  7. hibernate hql where语句拼接工具类

    package com.zhaoshijie.tree.other; /** * hibernate HQL WHERE语句工具类 * * @author 赵士杰 * */public class H ...

  8. Codeforces805 A. Fake NP 2017-05-05 08:30 327人阅读 评论(0) 收藏

    A. Fake NP time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  9. HDU1312 Red and Black(DFS) 2016-07-24 13:49 64人阅读 评论(0) 收藏

    Red and Black Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total ...

  10. hdu 1231 最大连续子序列 ,1003 Max Sum;

    题目(1231) #include<stdio.h> #include<iostream> using namespace std; int main() { int K,nu ...