Js事件流

CONTENTS
  • DOM事件流
  • 事件冒泡
  • 阻止冒泡
  • 事件捕获


DOM事件流

1.什么是事件流?javascript

事件流所描述的是从页面中接受事件的顺序css

2.DOM事件流的三个阶段?html

事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段java

3.DOM事件流三个阶段的执行顺序?浏览器

首先发生的事件捕获,为截取事件提供机会,而后是目标接受事件,最后是事件冒泡阶段,因此能够在最后一个阶段对事件做出响应。见下图更直观:bash


          在dom事件流中,事件的目标在捕获阶段不会接受到事件,这意味着在捕获阶段,事件从 document 到 div 后就中止了。下一个阶段是目标阶段,因而事件在 div 上发生,并在事件处理中被当作是冒泡阶段的一部分, 而后,冒泡阶段发生,事件又传回document。
dom


事件冒泡

1.什么是事件冒泡?
当事件发生后,这个事件就要开始传播(从里向外或者从外向里)函数

2.为何要传播?ui

由于事件源自己(可能)并无处理事件的能力,即处理事件的函数(方法)并未绑定在该事件源上。例如咱们点击一个按钮时,就会产生一个click事件,但这个按钮自己可能不能处理这个事件,事件必须从这个按钮传播出去,从而到达可以处理这个事件的代码中(例如咱们给按钮的onclick属性赋一个函数的名字,就是让这个函数去处理该按钮的click事件),或者按钮的父级绑定有事件函数,当该点击事件发生在按钮上,按钮自己并没有处理事件函数,则传播到父级去处理。spa

小案例代码以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>
<body>
    <div>
        <button>点击</button>
    </div>
</body>
</html>
复制代码

当咱们点击按钮button时,事件时这样传播的:

(1) button

(2) div

(3) body

(4) html

(5) document


阻止冒泡

1.为何要阻止冒泡?

例如:document上有A事件,div有B事件,div里面的span有C事件,若是不给span和div加阻止事件冒泡的话,点击span时就会触发到div的B事件、document的A事件,当点击span时不想触发div和document的事件就要加上阻止事件冒泡,div也是同样的道理,若是咱们不想让点击某个事件时父级受到影响,这时就应阻止冒泡。

eg:不加阻止冒泡事件,代码以下:

css代码:

<style type="text/css">
        .box1{width:200px;height:200px;background:pink;}
        .box2{width:100px;height:100px;background:gray;}
    </style>复制代码

​js+html代码:

<body>
    <div class="box1">
        <div class="box2"></div>
    </div>
    <script type="text/javascript">
        //获取对象
        var box1 = document.getElementsByClassName('box1')[0];
        var box2 = document.getElementsByClassName('box2')[0];
        //添加事件
        box1.onclick = function(){
            console.log('您点击了box1');
        }
        box2.onclick = function(){
            console.log('您点击了box2');
        }
    </script>
</body>复制代码

效果以下:


如图能够看出当点击 box1 时,只会提示‘您点击了box1’ 而点击 box2 时,居然输出了两句提示,若是咱们不想要这种效果,咱们只想要在点击了哪一个按钮后就执行该按钮的命令,也就是说阻止冒泡。

下面给出上述小案例的阻止冒泡方法:一句代码搞定,改变 box2 的触发事件,代码以下:

box2.onclick = function(e){
            console.log('您点击了box2');
            e.stopPropagation();
        }复制代码

效果图以下:这样就实现阻止冒泡


2.阻止冒泡的方法。

event.stopPropagation()方法 (这个方法小编在上面已经给出了例子,这里就不在给出具体的例子)

这是阻止事件的冒泡方法,不让事件向documen上蔓延,可是默认事件仍然会执行,当你调用这个方法的时候,若是点击一个链接,这个链接仍然会被打开,

event.preventDefault()方法

这是阻止默认事件的方法,调用此方法是,链接不会被打开,可是会发生冒泡,冒泡会传递到上一层的父元素;

下面给你们一个小例子:看图说话,在下面的空白处,不管我怎么点击右键,不管在什么位置点击,都会出现默认的东西,若是咱们不想要这种默认的东西怎么办呢?继续看图下面的案例,立刻带你飞,走起-------


eg:阻止浏览器右键默认事件

css代码:

<style type="text/css">
        *{margin:0;padding:0;}
        ul{list-style:none;}
        .box{position:relative;width:80px;border:1px solid gray;display: none;}
        .box  ul li{height:40px;line-height:40px;text-align:center;}
        .box  ul li:hover{background:#ccc;}
    </style>复制代码

 html+js代码:

<body>
  <div class='box'>
      <ul>
          <li>刷新</li>
          <li>删除</li>
          <li>命名</li>
      </ul>
  </div>
  <script type="text/javascript">
      //获取box对象
      var  box = document.getElementsByClassName('box')[0];
      //右键鼠标事件
      window.oncontextmenu = function(event){
        //阻止默认事件
        event.preventDefault();
        //获取鼠标点击某个位置的水平位置  X  和垂直位置   Y
        var  x=event.clientX;
        var  y=event.clientY;
        //改变 box 距离上面和左边的位置
        box.style.top = y + 'px';
        box.style.left = x + 'px';
        box.style.display = 'block';
      }
        window.onclick = function() {
            box.style.display = "none";
        }
  </script>
</body>
复制代码

效果以下:


return false(这里的例子就不赘述了,有心的小伙伴能够动手试试)

这个方法比较暴力,他会同时阻止事件冒泡也会阻止默认事件;写上此代码,链接不会被打开,事件也不会传递到上一层的父元素;能够理解为return false就等于同时调用了event.stopPropagation()和event.preventDefault()


事件捕获

事件捕获和事件冒泡是恰好相反的,事件捕获是指不太具体的节点应该更早的接收到事件,而最具体的节点应该最后接收到事件

案例走起:

css代码:

<style type="text/css">
        .box1{width:300px;height:300px;background:pink;}
        .box2{width:200px;height:200px;background:skyblue;}
        .box3{width:100px;height:100px;background:gray;}
    </style>复制代码

html+js代码:

​<body>    <div class="box1">
        <div class="box2">
            <div class="div box3"></div>
        </div>
    </div>
    <script type="text/javascript">
        //获取对象
        var box1 = document.getElementsByClassName('box1')[0];
        var box2 = document.getElementsByClassName('box2')[0];
        var box3 = document.getElementsByClassName('box3')[0];
        //点击事件
        box1.addEventListener('click',function(){
            console.log("捕获 box1");
        },true);
        box2.addEventListener('click',function(){
            console.log("捕获 box2");
        },true);
        box3.addEventListener('click',function(){
            console.log("捕获 box3");
        },true);

    </script>
</body>复制代码

动态效果以下:


当我点击最里面的 box3 时,咱们能够看到最外层的事件先被触发,最后才是咱们点击的 box3 事件被触发,这即是事件捕获。 

相关文章
相关标签/搜索