JS事件详解

in with 0 comment

事件流:描述的是在页面中接收事件的顺序

事件冒泡:由最具体的元素接收,然后逐级向上传播至最不具体的元素的节点

事件捕获:最不具体的节点先接收事件,而最具体的几点应该是最后接收事件

例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js事件</title>
</head>
<body>
    <div id="div">
        <button id="btn1">按钮</button>
    </div>
</body>
</html>
  1. 事件冒泡时:button接收 -----> div接收 -----> document接收
  2. 事件捕获时:document接收 -----> div接收 -----> button接收

事件冒泡使用的最多,目前的浏览器也都支持事件冒泡

事件处理

  1. HTML事件处理:直接添加到HTML结构中
  2. DOM 0级事件处理:把一个函数赋值给一个事件处理程序属性
  3. DOM 2级事件处理:addEventListener() removeEventListener()
  4. IE事件处理:attachEvent() detachEvent()

HTML事件处理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js事件</title>
</head>
<body>
    <div id="div">
        <button id="btn1" οnclick="demo()">按钮</button>
    </div>
    <script>
        function demo(){
            alert("hello,html事件处理");
        }
    </script>
</body>
</html>

缺点:修改一处代码则需要修改两处。例如把js中的函数名demo改了,则html文档里的button也需要修改。代码很多时会很麻烦。

DOM 0级事件处理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js事件</title>
</head>
<body>
    <div id="div">
        <button id="btn">按钮</button>
    </div>
    <script>
        var btn = document.getElementById("btn");
        btn.onclick = function () {
            alert("hello, DOM 0级事件处理程序");
        };
        // btn.onclick = null; // 清除当前事件
    </script>
</body>
</html>
  1. 优点:改动js中的函数时 不用改变HTML文档(中的button按钮)
  2. 缺点:有多个事件时,只会显示最后一个,前面的会被覆盖

例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js事件</title>
</head>
<body>
    <div id="div">
        <button id="btn">按钮</button>
    </div>
    <script>
        var btn = document.getElementById("btn");
        btn.onclick = function (){ alert("hello,DOM 0级事件处理程序1")};
        //btn.onclick = null;//清除当前事件
        btn.onclick = function (){ alert("hello,DOM 0级事件处理程序2")};
        btn.onclick = function (){ alert("hello,DOM 0级事件处理程序3")};
    </script>
</body>
</html>

只能显示第三个,前两个事件都被覆盖了

DOM 2级事件处理

addEventListener("事件名", "事件处理函数", "布尔值”) 添加事件 removeEventListener() 移除事件

false 事件冒泡 true 事件捕获

添加事件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js事件</title>
</head>
<body>
    <div id="div">
        <button id="btn">按钮</button>
    </div>
    <script>
        var btn = document.getElementById("btn");
        btn.addEventListener("click", demo1);
        btn.addEventListener("click", demo2);
        btn.addEventListener("click", demo3);
        function demo1() {
            alert("DOM 2级事件处理程序 1");
        }
        function demo2() {
            alert("DOM 2级事件处理程序 2");
        }
        function demo3() {
            alert("DOM 2级事件处理程序 3");
        }
    </script>
</body>
</html>

三个事件都会显示出来 ,并不会出现覆盖

移除事件
<script>
    var btn = document.getElementById("btn");
    btn.addEventListener("click", demo1);
    btn.addEventListener("click", demo2);
    btn.addEventListener("click", demo3);
    function demo1() {
        alert("DOM 2级事件处理程序 1");
    }
    function demo2() {
        alert("DOM 2级事件处理程序 2");
    }
    function demo3() {
        alert("DOM 2级事件处理程序 3");
    }
    btn.removeEventListener("click",demo2);
</script>

事件2被移除

IE事件处理

attachEvent() 添加事件
detachEvent() 移除事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js事件</title>
</head>
<body>
    <div id="div">
        <button id="btn">按钮</button>
    </div>
    <script>
        var btn = document.getElementById("btn");
        if (btn.addEventListener) {
            btn.addEventListener("click", demo);
        }
        else if (btn.attachEvent) {
            btn.attachEvent("onclick”, demo);
        }
        else {
            btn.onclick = demo();
        }
        function demo(){
            alert("hello");
        }
    </script>
</body>
</html>

如果支持addEventListener,进行DOM 2级操作 支持attachEvent,进行IE操作 否则进行DOM 0级操作

事件对象:在触发DOM事件时都会产生一个对象

属性

  1. type 获取事件类型
  2. target 获取事目标
事件属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js事件</title>
</head>
<body>
    <div id="div">
        <button id="btn">按钮</button>
    </div>
    <script>
        document.getElementById("btn").addEventListener("click", showType);
    
        function showType(event) {
            alert(event.type);
            // alert(event.target);
        }
 
    </script>
</body>
</html>

结果:点击按钮弹出事件类型“click” 将 alert(event.type) 注释,alert(event.target) 取消注释,点击按钮弹出事件对象 [object HTMLButtonElement] ,即HTML中的button元素

方法

  1. stopPropagation() 阻止事件冒泡
  2. preventDefault() 阻止事件默认行为
事件冒泡
<div id="div">
    <button id="btn">按钮</button>
</div>
<script>
    document.getElementById("btn").addEventListener("click", showType);
    document.getElementById("div").addEventListener("click", showDiv);
    function showType(event) {
        alert(event.type);
    }

    function showDiv(){
        alert("div");
    }
</script>

结果:点击按钮先后弹出“click”,"div" 解释:只点击了button,但是包含button的div也执行了,这属于事件冒泡,事件逐级向上传递,传给了div,有时并不需要事件冒泡,可以通过stopPropagation()

阻止事件冒泡
<div id="div">
    <button id="btn">按钮</button>
</div>
<script>
    document.getElementById("btn").addEventListener("click", showType);
    document.getElementById("div").addEventListener("click", showDiv);
    function showType(event) {
        alert(event.type);
        event.stopPropagation();
    }

    function showDiv(){
        alert("div");
    }
</script>
阻止事件默认行为
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js事件</title>
</head>
<body>
    <div id="div">
        <button id="btn">按钮</button>
        <a href="http://www.google.com" id="aid">阻止事件默认行为</a>
    </div>
    <script>
        document.getElementById("btn").addEventListener("click", showType);
        document.getElementById("div").addEventListener("click", showDiv);
        document.getElementById("aid").addEventListener("click", showA);
        function showType(event) {
            alert(event.type);
            event.stopPropagation();
        }
 
        function showDiv() {
            alert("div");
        }
 
        function showA(event) {
            event.stopPropagation(); //阻止事件冒泡
            event.preventDefault();    //阻止事件的默认行为
        }
    </script>
</body>
</html>

a标签的默认属性是跳转到相应链接,不想点击链接跳转到相应页面时,使用event.preventDefault()阻止a标签的跳转