JavaScript

JS事件冒泡与事件捕获

下文笔者讲述事件冒泡简介及事件捕获的简介说明,如下所示

事件冒泡的简介

事件冒泡指:
    点击一个事件,同时向上触发的一系列事件
	我们将这种现象称之为“事件冒泡”

事件冒泡及事件捕获提出者

事件捕获:
   由微软公司提出
    事件从文档根节点(Document 对象)流向目标节点
    途中会经过目标节点的各个父级节点
    并在这些节点上触发捕获事件,直至到达事件的目标节点;
事件冒泡:
    由网景公司提出
    与事件捕获相反
    事件会从目标节点流向文档根节点
    途中会经过目标节点的各个父级节点
    并在这些节点上触发捕获事件
    直至到达文档的根节点
     整个过程就像水中的气泡一样,从水底向上运动。

事件冒泡的示例

<body>
    <div id="wrap">
        <p class="hint">
            <a href="#">Click Me</a>
        </p>
    </div>
</body>
以上代码,在点击了Click Me后
p 标签和div标签上的点击事件也会被触发
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>linux28.com JavaScript</title>
    <style type="text/css">
        div, p, a {
            padding: 15px 30px;
            display: block;
            border: 2px solid #000;
            background: #fff;
        }
    </style>
</head>
<body>
    <div id="wrap">DIV
        <p class="hint">P
            <a href="#">A</a>
        </p>
    </div>
    <script>
        function showTagName() {
            alert("事件捕获: " + this.tagName);
        }
        var elems = document.querySelectorAll("div, p, a");
        for (let elem of elems) {
            elem.addEventListener("click", showTagName, true);
        }
    </script>
</body>
</html>
单击最内层的<a>标签

事件冒泡

事件冒泡正好与事件捕获相反
   事件冒泡是从目标节点开始
   沿父节点依次向上
   并触发父节点上的事件
   直至文档根节点
   就像水底的气泡一样,会一直向上。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript</title>
    <style type="text/css">
        div, p, a {
            padding: 15px 30px;
            display: block;
            border: 2px solid #000;
            background: #fff;
        }
    </style>
</head>
<body>
    <div onclick="alert('事件冒泡: ' + this.tagName)">DIV
        <p onclick="alert('事件冒泡: ' + this.tagName)">P
            <a href="#" onclick="alert('事件冒泡: ' + this.tagName)">A</a>
        </p>
    </div>
</body>
</html>

阻止事件捕获和冒泡

JavaScript中提供stopPropagation()方法
    阻止事件捕获和事件冒泡的发生
  语法格式如下:
     event.stopPropagation();
    stopPropagation() 会阻止事件捕获和事件冒泡
    但无法阻止标签的默认行为
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>linux28.com JavaScript</title>
    <style type="text/css">
        div, p, a {
            padding: 15px 30px;
            display: block;
            border: 2px solid #000;
            background: #fff;
        }
    </style>
</head>
<body>
    <div id="wrap">DIV
        <p class="hint">P
            <a href="#">A</a>
        </p>
    </div>
    <script>
        function showAlert(event) {
            alert("您点击了 "+ this.tagName + " 标签");
            event.stopPropagation();
        }
        var elems = document.querySelectorAll("div, p, a");
        for(let elem of elems) {
            elem.addEventListener("click", showAlert);
        }
    </script>
</body>
</html>

stopImmediatePropagation()方法

stopImmediatePropagation()方法的功能:
    阻止同一节点的同一事件的其它事件处理程序
    如
	  为某个节点定义了多个点击事件
      当事件触发时,这些事件会按定义顺序依次执行
    当其中一个事件处理程序中使用stopImmediatePropagation()方法
     则剩下的事件处理程序将不再执行 

stopImmediatePropagation() 方法的语法格式如下:
	event.stopImmediatePropagation();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>linux28.com JavaScript</title>
    <style type="text/css">
        div, p, a {
            padding: 15px 30px;
            display: block;
            border: 2px solid #000;
            background: #fff;
        }
    </style>
</head>
<body>
    <div onclick="alert('您点击了 ' + this.tagName + ' 标签')">DIV
        <p onclick="alert('您点击了 ' + this.tagName + ' 标签')">P
            <a href="#" id="link">A</a>
        </p>
    </div>
    <script>
        function sayHi() {
            alert("事件处理程序 1");
            event.stopImmediatePropagation();
        }
        function sayHello() {
            alert("事件处理程序 2");
        }
        // 为 id 为 link 的标签定义多个点击事件
        var link = document.getElementById("link");
        link.addEventListener("click", sayHi); 
        link.addEventListener("click", sayHello);
    </script>
</body>
</html>

阻止默认操作

某些事件具有与之关联的默认操作
 
 例:
  当您单击某个链接时,会自动跳转到指定的页面
  当您单击提交按钮时,会将数据提交到服务器等
  
  如果不想这样的默认操作发生,可使用preventDefault()方法来阻止
   其语法格式如下:
     event.preventDefault();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript</title>
</head>
<body>
    <a href="https://www.linux28.com/" id="link">链接</a>
    <script>
        var link = document.getElementById("link");
        link.addEventListener('click', function(event){
            event.preventDefault(); // 阻止链接跳转
        });
    </script>
</body>
</html>
注意事项:
    IE9及以下的版本不支持preventDefault()方法
    对于IE9及以下的浏览器可使用event.returnValue = false