事件

概述

绑定事件

    <button>按钮</button>
    <script>
        let btn = document.querySelector("button");
        
        //以前绑定事件的方法 元素.on事件类型=function(){}
        /*
        btn.onclick = function(){
            console.log("hello");
        }
        */
       //新的绑定事件方法 元素.addEventListener("事件类型",function(){})
       btn.addEventListener("click",function(){
        console.log("hello");
       });
    </script>

两者区别

    <button>按钮</button>
    <script>
        let btn = document.querySelector("button");
        
        /*
        btn.onclick=function(){
            console.log("hello click1")
        }
        btn.onclick=function(){
            console.log("hello click2")
        }//结果会输出hello click2
        //通过赋值添加事件,后面的事件会覆盖掉前面的
        */
       btn.addEventListener("click",function(){
            console.log("hello click1")
       })
       btn.addEventListener("click",function(){
            console.log("hello click2")
       })
    </script>

事件流

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .big{
            width: 300px;
            height: 300px;
            background-color: red;
        }
        .middle{
            width: 200px;
            height: 200px;
            background-color: blue;
        }
        .small{
            width: 100px;
            height: 100px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div class="big">
        <div class="middle">
            <div class="small"></div>
        </div>
    </div>
    <script>
        let big = document.querySelector(".big")
        let middle = document.querySelector(".middle")
        let small = document.querySelector(".small")

        big.addEventListener("click",function(){
            console.log("big")
        })
        middle.addEventListener("click",function(){
            console.log("middle")
        })
        small.addEventListener("click",function(){
            console.log("small")
        })
    </script>
</body>
</html>


结果说明事件触发是从内到外的,即在事件冒泡阶段

事件捕获与事件冒泡

        big.addEventListener("click",function(){
            console.log("big")
        },true)
        middle.addEventListener("click",function(){
            console.log("middle")
        },true)
        small.addEventListener("click",function(){
            console.log("small")
        },true)


了解即可,绝大多数情况下都是在冒泡阶段执行事件

阻止事件冒泡e.stopPropagation()

阻止冒泡阶段触发多个事件

        big.addEventListener("click",function(){
            console.log("big")
        })
        middle.addEventListener("click",function(){
            console.log("middle")
        })
        small.addEventListener("click",function(e){
            console.log("small")
            e.stopPropagation()
        })


点击黄色区域,输出只有small,阻止了外层的事件执行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box{
            width: 200px;
            height: 200px;
            background-color: yellow;
            display: none;
        }
    </style>
</head>
<body>
    <div class="show">
        <button>显示</button>
    </div>
    <div class="box">
        <div class="close">
            <button>关闭</button>
        </div>
    </div>
    <script>
        let show = document.querySelector(".show")
        let box = document.querySelector(".box")
        let close = document.querySelector(".close")

        show.addEventListener("click",function(){
            box.style.display = "block"
        })
        close.addEventListener("click",function(){
            box.style.display = "none"
        })
        box.addEventListener("click",function(){
            box.style.backgroundColor = "red"
        })
    </script>
</body>
</html>

点击显示

现在有个bug,如果直接点关闭,再点显示,box的颜色也会变成红色

因为点击关闭触发close的事件,又因为close有外部事件box,所以也会触发box事件改变颜色
要避免这种情况就要在close事件加个e.stopPropagation()

        close.addEventListener("click",function(e){
            box.style.display = "none"
            e.stopPropagation()
        })

阻止事件默认行为e.preventDefault()/return false

    <a href="http://baidu.com">baidu</a>
    <script>
        let baidu = document.querySelector("a")
        baidu.addEventListener("click",function(){
            console.log("baidu")
        })
    </script>

点击baidu就会跳转到baidu网页,同时在控制台输出baidu
如果只想输出baidu,那可以用e.preventDefault()

    <a href="http://baidu.com">baidu</a>
    <script>
        let baidu = document.querySelector("a")
        baidu.addEventListener("click",function(e){
            console.log("baidu")
            e.preventDefault()
        })
    </script>

另一种写法

    <a href="http://baidu.com">baidu</a>
    <script>
        let baidu = document.querySelector("a")
        baidu.onclick = function(e){
            console.log("baidu")
            return false//对addEventListener无效
        }
    </script>

事件委托

通过事件冒泡的原理,通过e.target将子级的事件委托给父级完成

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="text">
    <button>添加</button>
    <ul class="fruits">
        <li>苹果</li>
        <li>香蕉</li>
        <li>雪梨</li>
    </ul>
    <script>
        let btn = document.querySelector("button")
        let inp = document.querySelector("input")
        let ul = document.querySelector(".fruits")

        btn.addEventListener("click",function(){
            let li = document.createElement("li")
            let value = inp.value
            let txt = document.createTextNode(value)
            li.appendChild(txt)
            ul.appendChild(li)
        })

        //事件委托
        ul.addEventListener("click",function(e){
            ul.removeChild(e.target)
            /*e.target是触发该事件的子元素,这里是点击的li标签
            因为点击li标签虽然li本身没有事件,但它的外层即父级有绑定点击事件
            就是这里的ul事件
            */
        })
    </script>
</body>
</html>

通过事件委托的方法可以解决上一章节无法删除新添加的li标签的问题

事件类型

键盘事件

document.addEventListener("keydown",function(){
            //keydown类型能通过按下任意键触发事件
            console.log("hello")//按任意键打印hello
        })

        document.addEventListener("keydown",function(e){
            console.log(e.keyCode)//输出按键对应的码值,且不区分大小写,如a和A=65
        })

  • 通过键盘移动方块
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box{
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            top: 100px;
            left: 100px;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script>
        let box = document.querySelector(".box");
        /*
        offset方向:距离某个方向的偏移量
        console.log(box.offsetTop);//100 距离上侧的偏移量是100px
        console.log(box.offsetLeft);//100 距离左侧的偏移量是100px
        */
        document.addEventListener("keydown",function(e){
            let code = e.keyCode//左上右下的键值是37,38,39,40
            switch(code){
                case 37:
                    box.style.left = box.offsetLeft - 5 + "px";
                    break;
                case 38:
                    box.style.top = box.offsetTop - 5 + "px";
                    break;    
                case 39:
                    box.style.left = box.offsetLeft + 5 + "px";
                    break;
                case 40:
                    box.style.top = box.offsetTop + 5 + "px";
                    break; 
            }
        });
    </script>
</body>
</html>

触屏事件

    <style>
        .box{
            width: 100px;
            height: 100px;
            background-color: red;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script>
        let box = document.querySelector(".box");
        box.addEventListener("touchstart",function(){
            //touchstart是手机的触屏后(手指抬起前)会触发事件
            console.log("start");
        });
        box.addEventListener("touchend",function(){
            //touchend是手指抬起屏幕后会触发事件
            console.log("end");
        });
        box.addEventListener("touchmove",function(){
            //touchmove是手指按住屏幕并移动时(即划动屏幕)会触发事件
            console.log("move");
        });
    </script>
</body>
</html>

posted @ 2022-10-28 21:07  ben10044  阅读(64)  评论(0编辑  收藏  举报