【十四】JavaScript之DOM中的事件操作

【十四】JavaScript之DOM中的事件操作

【1】事件操作

  • 所谓的事件(Event),其实就是用户与浏览器之间的一次交互过程或交互行为。

    • 例如:用户输入一段内容,用户鼠标晃动一下等等。
  • js中提供了大量的事件操作给开发者, 在用户发生事件操作以后,进行反馈,响应。

  • 事件类型有很多,但是操作基本都是一样的,只是里面的代码因为事件的不同,而执行的方式,属性不同而已。

【2】事件类型

  • js中针对用户与浏览器之间的交互方式不同,提供了多种类型的事件,常用的有例如:鼠标事件、键盘事件、表单事件、窗口事件等。
类型事件描述
鼠标事件click鼠标点击事件
鼠标事件mouseover鼠标滑过事件
鼠标事件dblclick鼠标双击事件
鼠标事件mouseout鼠标离开事件
鼠标事件mouseup鼠标松开事件
鼠标事件mousedown鼠标按下事件
鼠标事件mousemove鼠标移动事件
表单事件focus获取焦点事件
表单事件blur失去焦点事件
表单事件change输入框/选择框值改变事件
表单事件select在文本框中选择文本时
表单事件submit表单提交
键盘事件keydown键盘按下
键盘事件keyup键盘松开
键盘事件onkeypress按下并松开
窗口事件onload页面加载内容完成以后自动触发当前事件
在js中使用事件时,必须事件名称左边加上on
例如:给一个元素绑定点击事件则是 onclick...

(1)鼠标事件

  • 鼠标事件一个绑定给所有的HTML元素
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    * {
        margin: 0;
        padding: 0;
    }
    .btn2, .btn3, .btn4{
        width: 100px;
        height: 42px;
        background: red;
    }
    .btn4{
        position: absolute;
        top: 0;
        left: 0;
    }
    </style>
</head>
<body>
<!--    <button class="btn1">点击跳转到百度</button>-->
<!--    <div class="btn2"></div>-->
<!--    <div class="btn3"></div>-->
    <div class="btn4"></div>
    <script>
    // // click 点击事件
    // var btn1 = document.querySelector(".btn1")
    // btn1.onclick = function(){
    //     location.assign("https://www.baidu.com")
    // }
    //
    // // dblclick 双击事件[一秒内连续鼠标点击2次]
    // var btn2 = document.querySelector(".btn2")
    // btn2.ondblclick = function(){
    //     btn2.style.background = "yellow";
    // }
    //
    // // mouseover 鼠标悬放
    // var btn2 = document.querySelector(".btn2")
    // btn2.onmouseover = function(){
    //     console.log("只要鼠标在当前元素上方悬放就会触发一次")
    //     btn2.style.background = "orange";
    // }
    //
    // // mouseout 鼠标离开
    // var btn2 = document.querySelector(".btn2")
    // btn2.onmouseout = function(){
    //     console.log("只要鼠标从当前元素上方离开就会触发一次")
    //     btn2.style.background = "red";
    // }
    //
    // // mousedown 鼠标按下
    // var btn3 = document.querySelector(".btn3")
    // btn3.onmouseout = function(){
    //     console.log("只要鼠标从当前元素上方离开就会触发一次")
    //     btn3.style.background = "red";
    // }
    //
    // // mousedown 鼠标按下
    // var btn3 = document.querySelector(".btn3")
    // btn3.onmousedown = function(){
    //     console.log("鼠标在当前元素范围内按下,就会触发事件")
    //     btn3.style.background = "blue";
    // }
    //
    // // mouseup 鼠标松开
    // var btn3 = document.querySelector(".btn3")
    // btn3.onmouseup = function(){
    //     console.log("鼠标在当前元素范围内从按下变成松开,就会触发事件")
    //     btn3.style.background = "green";
    // }

    // // mousemove 鼠标移动
    // var btn4 = document.querySelector(".btn4")
    // btn4.onmousemove = function(event){
    //     console.log("鼠标在当前元素范围内移动,就会触发事件")
    //     // console.log(this.offsetLeft) // 距离浏览器窗口左边的宽度
    //     // console.log(event.clientX)   // 当前事件发生时,鼠标位置距离浏览器窗口左边的宽度
    //     console.log(event.offsetX)      // 当前事件发生时,鼠标位置距离当前元素的左边的宽度
    // }

    // 鼠标拖拽效果[基于原生js提供的鼠标按下事件,和鼠标移动事件]
    var btn4 = document.querySelector(".btn4")
    btn4.onmousedown = function(event){
        // 鼠标按下
        let startX = event.clientX-this.offsetLeft; // 记录每次鼠标按下时坐标
        let startY = event.clientY-this.offsetTop;
        btn4.onmousemove = function(e){
            // 鼠标移动
            this.style.left = `${e.clientX - startX}px`; // 计算鼠标移动的距离
            this.style.top = `${e.clientY - startY}px`;
        }
    }

    btn4.onmouseup = function(){
        console.log("鼠标离开了当前元素范围!");
        btn4.onmousemove = null;
    }
    </script>
</body>
</html>

(2)表单事件

  • 表单事件一般是绑定表单元素的
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>

    </style>
</head>
<body>
    <div class="loginbox">
        登录账号:<input type="text" name="username" placeholder="请输入账号!"><b></b><br>
        登录密码:<input type="password" name="password" placeholder="请输入密码!"><br>
        确认密码:<input type="password" name="password2" placeholder="请再次输入密码!"><br>
        所在城市:<select name="city">
                    <option value="beijing">北京</option>
                    <option value="shanghai">上海</option>
                    <option value="chongqing">重庆</option>
                    <option value="guiyang">贵阳</option>
                </select><br>
        <input type="file" name="avatar" id="">
    </div>
    <script>
    var username = document.querySelector('input[name="username"]')
    var password = document.querySelector('input[name="password"]')
    // 获取焦点
    username.onfocus = function(){
        username.style.outline = "1px solid rgba(255, 99,99, 1)";
        if(username.nextElementSibling.innerHTML){
            username.value = "";
            username.nextElementSibling.innerHTML = "";
        }
    }

    // 失去焦点
    username.onblur = function(){
        username.style.outline = "none";
        if(username.value.length<3 || username.value.length>16){
            username.nextElementSibling.innerHTML = "账号的账号必须在3-16个字符之间"
        }
    }
    // 值改变[输入框,下拉框,文件上传等]
    password.onchange = function(){
        console.log(password.value);
    }
    var city = document.querySelector('select[name="city"]');
    city.onchange = function(){
        console.log(city.value)
        console.log(city.options.selectedIndex)
    }

    var avatar = document.querySelector('input[name="avatar"]');
    avatar.onchange = function(){
        console.dir(avatar.value);
    }
    </script>
</body>
</html>

(3)键盘事件

  • 一般是绑定window,document,表单输入类型元素的。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>

    </style>
</head>
<body>
    <form action="https://httpbin.org/post" method="post">
        <input type="text" name="username">
        <button>登录</button>
    </form>
    <script>
    // // keyup 键松开
    // document.onkeyup = function(event){
    //     console.log(`本次按了:${event.keyCode}键`)
    // }
    //
    // // keydown 键按下
    // document.onkeydown = function(event){
    //     console.log(`本次按了:${event.keyCode}键`)
    // }
    // var username = document.querySelector('input[name="username"]')
    // username.onkeyup = function(){
    //     if(username.value.length<3 || username.value.length>16){
    //         username.style.outline = "1px solid red";
    //     }else{
    //         username.style.outline = "1px solid blue";
    //     }
    // }

    // 回车键直接提交表单
    window.onkeyup = function(event){
        if(event.keyCode === 13){
            console.log("按了回车键");
            document.querySelector('form').submit(); // 直接触发事件
        }
    }

    </script>
</body>
</html>

(4)窗口事件

  • 窗口事件一般只给window绑定。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
    // // 直接执行肯定报错,我们需要让代码延时执行。
    // var h1 = document.querySelector("h1"); // 这段代码执行的时候,浏览器根本不知道找到前面的内容有h1出现
    // console.log(h1);
    // console.log(h1.innerHTML);

    // 1. 使用window.onload,保证页面内容加载完成以后才执行js代码
    //    但是window.onload只能使用一次,多次绑定函数,只会识别最后一次
    window.onload = function(){
        console.log("window onload")
        var h1 = document.querySelector("h1"); // 这段代码执行的时候,浏览器根本不知道找到前面的内容有h1出现
        console.log(h1);
        console.log(h1.innerHTML);
    }

    //2. 使用setTimeout来完成延时执行,因为setTimeout的执行时在页面加载完成以后才会执行的
    //   比window.onload要好用,可以使用多次。
    setTimeout(()=>{
        console.log("setTimeout1")
        var h1 = document.querySelector("h1"); // 这段代码执行的时候,浏览器根本不知道找到前面的内容有h1出现
        console.log(h1);
        console.log(h1.innerHTML);
    }, 0)

    setTimeout(()=>{
        console.log("setTimeout2")
        var h1 = document.querySelector("h1"); // 这段代码执行的时候,浏览器根本不知道找到前面的内容有h1出现
        console.log(h1);
        console.log(h1.innerHTML);
    }, 0)

    </script>
</head>
<body>
<h1>标题</h1>
<script>
    // window.onload = function(){
    //     console.log("页面加载完成才会触发当前事件!!")
    // }
    console.log("hello")


</script>
</body>
</html>

【3】事件的绑定

基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
    <ul>
        <li>1-内容</li>
        <li onclick="show_data(this)">2-内容</li>
        <li class="li3">3-内容</li>
        <li>4-内容</li>
        <li>5-内容</li>
    </ul>
<script>
    // var li = document.querySelector("li")
    // // 动态绑定事件:在js中获取元素,并基于元素对象进行事件绑定
    // li.onclick = function(){
    //     console.log(this.innerHTML)
    // }
    //
    // // 静态绑定事件:在html标签中,使用属性的方式来绑定事件
    // function show_data(element){
    //     console.log(element); // element就是当前触发事件时传递进行来的当前元素对象
    //     console.log(event);   // 静态绑定事件触发时,当前事件对象
    // }
    //
    // /*动态绑定在工作中更加常用*/
    // // 事件解绑,绑定时是什么类型的事件,解绑时就要对当前类型事件进行赋值为null
    // li.onclick = null;


    /**
     * addEventListner(事件类型,事件处理函数)      绑定事件
     * removeEventListner(事件类型,事件处理函数)   解绑事件
     * EventListner 表示事件监听器,是属于js事件操作的最新用法,
     * onclick属于level1.0版本的事件处理机制,无法对同一个元素多次绑定事件处理函数,
     * EventListner属于level3.0版本的事件处理机制,可以对同一个元素多次绑定事件处理函数
     */
    var li3 = document.querySelector(".li3")

    // 事件处理函数,可以是任意函数
    var li_click = (event)=>{
        console.log("li_click")
        console.log(event);
        console.log(event.target); // target 可以获取当前事件触发时的元素对象
    }

    var li2_click = (event)=>{
        console.log("li2_click")
        console.log(event);
        console.log(event.target); // target 可以获取当前事件触发时的元素对象
    }

    li3.addEventListener("click", li_click);
    li3.addEventListener("click", li2_click);
    // 事件解绑时,要指定解绑的是哪一个函数
    // li3.removeEventListener("click", li_click);

    // 针对元素如果使用level3.0的事件处理机制,绑定多次事件处理函数时,
    // 可以通过F12浏览器调试工具->console->EventListeners来查看
</script>
</body>
</html>

动态绑定事件[常用]

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .box{
        width: 100px;
        height: 100px;
        background-color: red;
    }
    </style>
</head>
<body>
    <button id="hide">隐藏</button>
    <button id="show">显示</button>
    <div class="box"></div>
    <h1>hello</h1>
    <script>
    let hide = document.querySelector("#hide");
    let show = document.querySelector("#show");
    let box = document.querySelector(".box");
    // hide.onclick = function(){
    //     box.style.display = "none";
    // }
    // show.onclick =function(){
    //     box.style.display = "block"
    // }
    // let timer = null;
    // hide.onclick = function(){
    //     let opacity = parseFloat(getComputedStyle(box)["opacity"])
    //     clearInterval(timer)
    //     timer = setInterval(()=>{
    //         if(opacity<=0){
    //             box.style.display = "none";
    //             clearInterval(timer)
    //         }else{
    //             opacity-=0.02
    //             box.style.opacity = opacity;
    //         }
    //     },25)
    // }
    // show.onclick = function(){
    //     let opacity = parseFloat(getComputedStyle(box)["opacity"])
    //     box.style.display = "block";
    //     clearInterval(timer)
    //     timer = setInterval(()=>{
    //         if(opacity>=1){
    //             clearInterval(timer)
    //         }else{
    //             opacity+=0.02
    //             box.style.opacity = opacity;
    //         }
    //     },25)
    // }

    let timer = null;
    hide.onclick = function(){
        box.style.position = "relative"
        let top = parseFloat(getComputedStyle(box)["top"])
        clearInterval(timer)
        timer = setInterval(()=>{
            if(top == 0 ){
                top-=1
            }
            if(top <=-1){
                top*=1.4
            }
            if(top <= -window.outerHeight){
                box.style.height="0px"
                clearInterval(timer)
            }
            box.style.top =  parseInt(top)+'px';
        },24)
    }

    show.onclick = function(){
        box.style.position = "relative"
        let top = parseFloat(getComputedStyle(box)["top"])
        clearInterval(timer)
        box.style.height="100px";
        timer = setInterval(()=>{
            if(top>=0){
                box.style.top="0px";
                clearInterval(timer)
            }else{
                top*=0.9
                box.style.top = parseInt(top)+'px';
            }
        },24)
    }


    </script>
</body>
</html>

静态绑定事件

  • 直接给标签元素以"on+事件名"这种方式绑定事件,称之为静态绑定
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .box{
        width: 100px;
        height: 100px;
        background-color: red;
    }
    </style>
</head>
<body>
    <button onclick="hide1()">隐藏</button>
    <button onclick="show1()">显示</button>
    <div class="box" onmouseover="change_color(true)" onmouseout="change_color(false)"></div>
    <script>
    var box = document.querySelector(".box");
    function hide1(){
        // 隐藏div
        let width = parseInt(getComputedStyle(box)["width"]);
        let height = parseInt(getComputedStyle(box)["height"]);
        let timer = setInterval(()=>{
            box.style.width = --width+"px";
            box.style.height = --height+"px";
            if(width<1){
                clearInterval(timer); // 停止定时器的执行
            }
        },3);
    }
    function show1(){
        // 显示div
        let width = parseInt(getComputedStyle(box)["width"]);
        let height = parseInt(getComputedStyle(box)["height"]);
        let timer = setInterval(()=>{
            box.style.width = ++width+"px";
            box.style.height = ++height+"px";
            if(width>100){
                clearInterval(timer); // 停止定时器的执行
            }
        },3);
    }

    function change_color(type){
        if(type){
            box.style.backgroundColor="blue";
        }else{
            box.style.backgroundColor="red";
        }
    }


    </script>
</body>
</html>

动态绑定与静态绑定的区别

动态绑定,根据已存在的元素对象指定事件处理的,而静态绑定,实际上是根据HTML代码结合事件处理函数来处理的。所以针对元素如果属于js代码动态生成,动态绑定有可能无法处理。

以下情况使用动态绑定,就不好处理。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <button class="add">添加</button>
    <ul class="box">

    </ul>
    <script>
    var add = document.querySelector(".add")
    var box = document.querySelector(".box")
    add.onclick = function(){
        box.innerHTML+= `<li><input type="text"><button onclick="sub(this)">-</button></li>`
    }
    function sub(ele){
        ele.parentElement.remove();
    }
    </script>
</body>
</html>

【4】批量绑定事件

  • 表示一次性给多个元素绑定事件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        <li>1-</li>
        <li>2-</li>
        <li>3-</li>
    </ul>
    <script>
        var list = document.querySelectorAll("li")
        // 如果循环,函数,方法中的变量尽可能使用let进行声明。
        // 其他地方的变量则可以使用var声明
        for(let i = 0; i<list.length; i++){
            list[i].onclick = function(){
                console.log(i, list[i].innerHTML);
                // console.log(this.innerHTML)
            }
        }
        // console.log(i); // for循环中使用let声明,不要使用var,否则i会变成全局变量。
    </script>
</body>
</html>

【5】事件的操作

  • 在事件处理函数中,可以根据event事件处理机制,在函数内部通过当前时间对象完成事件周边操作
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <button class="btn">点击按钮</button>
    </div>
    <script>
    var btn = document.querySelector(".btn")
    var func1 = function(event){
        console.log(event); // 当前事件对象,MouseEvent 表示鼠标事件
        console.log(event.target) // 触发事件的元素对象
        console.log(event.timeStamp) // 触发事件时,客户端的时间戳
        console.log(event.type) // 触发事件的事件类型
        console.log(event.path) // 事件触发过程中的事件捕获/事件传播路径
    }
    btn.addEventListener("click", func1);
    </script>
</body>
</html>

【6】事件的传播机制

  • 事件在用户触发时,实际上在js中内部处理过程中,分2个阶段:
    • 冒泡阶段与捕获阶段。
  • 冒泡阶段:
    • 从事件发生的最开始元素(event.target),从内层往外层,逐层查找事件处理函数,这个过程就是冒泡阶段。
  • 捕获阶段:
    • 从窗口(window)调用事件处理函数,从外层往内层逐步查找元素冒泡路径的过程,这就是捕获阶段。

【7】事件冒泡

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body onclick="show(this)">
    <div class="box1"  onclick="show(this)">
        <h1>标题</h1>
        <p class="p1" onclick="show(this)">
            <span>文章内容</span><br>
            <a href="" class="a1" onclick="return show(this)">a标签内容</a>
        </p>
    </div>
    <script>
    function show(ele){
        console.log(ele);
        return false; // 阻止页面跳转或表单提交
    }
    </script>
</body>
</html>
  • 在事件触发时,事件的影响出内往外进行逐层传递,这个过程就是事件冒泡(Event Propagation),有好处也有坏处。

  • 好处:

    • 我们可以批量的元素操作的事件,基于事件委托让父元素进行代理绑定,避免在动态绑定时对于动态生成的HTML元素不可控的情况。
  • 坏处:

    • 有时候父元素与子元素绑定同类型事件时,父元素不希望被触发的事件,会因为子元素被触发了而直接执行。
  • 阻止事件冒泡

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .login-btn{
        border: none;
        outline: none;
        background: #315efb;
        color: #fff;
        width: 120px;
        height: 48px;
        line-height: 48px;
        text-align: center;
        border-radius: 5px;
        cursor: pointer;
        font-size: 18px;
    }
    .login-bg{
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
        display: none;
        background-color: rgba(0,0,0,0.67);
    }
    .login-box{
        width: 400px;
        height: 180px;
        padding: 100px;
        background-color: #fff;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
    }
    </style>
</head>
<body>
    <button class="login-btn">登录</button>
    <div class="login-bg">
        <div class="login-box">
            <h2>登录</h2>
            登录账号:<input type="text"><br><br>
            登录密码:<input type="password" name="" id=""><br><br>
            <input type="submit" value="登录">
        </div>
    </div>
    <script>
    let btn = document.querySelector(".login-btn")
    let bg = document.querySelector(".login-bg")
    let box = document.querySelector(".login-box")
    btn.onclick = function(){
        bg.style.display = "block"
    }
    bg.onclick = function(){
        bg.style.display = "none";
    }
    box.onclick = function(event){
        console.log("备点了")
        // 阻止事件继续冒泡
        event.stopPropagation()
    }
    </script>
</body>
</html>

【8】事件委托

  • 利用事件冒泡实现事件委托(也叫事件委派)
    • 基于事件冒泡的特点,让子元素被触发事件以后的事件处理函数绑定到父元素中。
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>作业</title>
  <style>
  *{ padding: 0;margin: 0; }
  ul,li{list-style: none; }
  ul{
    width: 868px;
    height: 374px;
    background: #f5f5f5;
    margin: 10px auto 0;
  }
  ul li{
    position: relative;
    float: left;
    margin: 1px 1px 0px;
    height: 92px;
    width: 122px;
  }
  #opacity{
    position: absolute;
    top: 0;
    left: 0;
    width: 122px;
    height: 92px;
    background: #000;
    opacity: .8;
    cursor: pointer;
  }
  #opacity img{
    float: right;
    margin: 14px 12px 10px 0px;
  }
  #opacity p{
    color: #fff;
    font-size: 11px;
    text-align: center;
  }
  #opacity input{
    display: block;
    margin: 15px auto 0;
    background: #f00;
    width: 63px;
    height: 18px;
    line-height: 18px;
    border: none;
    border-radius: 8px;
    color: #fff;
    font-size: 11px;
    text-align: center;
    outline: none;
  }
  .clear{
    clear: both;
  }
  </style>
</head>
<body>
  <ul>
    <li data-number="15.0">
      <img src="images/1.png" alt="">
      <div id="opacity">
        <img src="images/lve.png" alt="">
        <div class="clear"></div>
        <p>关注人数 15.0万</p>
        <input type="button" value="点击进入">
      </div>
    </li>
    <li data-number="20.0"><img src="images/2.png" alt=""></li>
    <li data-number="7.0"><img src="images/3.png" alt=""></li>
    <li data-number="15.3"><img src="images/4.png" alt=""></li>
    <li data-number="15.6"><img src="images/5.png" alt=""></li>
    <li data-number="24.0"><img src="images/6.png" alt=""></li>
    <li data-number="39.0"><img src="images/7.png" alt=""></li>
    <li data-number="8.0"><img src="images/1.png" alt=""></li>
    <li data-number="55.0"><img src="images/2.png" alt=""></li>
    <li data-number="43.0"><img src="images/3.png" alt=""></li>
    <li data-number="12.0"><img src="images/4.png" alt=""></li>
    <li data-number="34.0"><img src="images/5.png" alt=""></li>
    <li data-number="22.0"><img src="images/6.png" alt=""></li>
    <li data-number="12.0"><img src="images/7.png" alt=""></li>
    <li data-number="21.0"><img src="images/1.png" alt=""></li>
    <li data-number="42.0"><img src="images/2.png" alt=""></li>
    <li data-number="22.0"><img src="images/3.png" alt=""></li>
    <li data-number="52.0"><img src="images/4.png" alt=""></li>
    <li data-number="21.0"><img src="images/5.png" alt=""></li>
    <li data-number="17.0"><img src="images/6.png" alt=""></li>
    <li data-number="12.0"><img src="images/7.png" alt=""></li>
    <li data-number="3.0"><img src="images/1.png" alt=""></li>
    <li data-number="1.0"><img src="images/2.png" alt=""></li>
    <li data-number="0.5"><img src="images/3.png" alt=""></li>
    <li data-number="1.4"><img src="images/4.png" alt=""></li>
    <li data-number="2.0"><img src="images/5.png" alt=""></li>
    <li data-number="4.0"><img src="images/6.png" alt=""></li>
    <li data-number="5.0"><img src="images/7.png" alt=""></li>
  </ul>
<script>
  // // 1. 批量绑定事件
  // var list = document.querySelectorAll("li")
  // var opacity = document.querySelector("#opacity")
  // for(let i = 0; i<list.length; i++){
  //   list[i].addEventListener("mouseover", show);
  // }

  // function show(event){
  //   if(event.target.parentElement.tagName === "LI"){
  //     // console.log(event.target.parentElement.dataset); // 获取HTML元素中以data-开头的属性
  //     let num = event.target.parentElement.dataset.number;
  //     opacity.querySelector("p").innerHTML = `关注人数 ${num}万`
  //     event.target.parentElement.appendChild(opacity);
  //   }
  // }


  // 事件委托: 把子元素的事件处理函数委托给父元素触发
  var ul = document.querySelector("ul")
  ul.addEventListener("mouseover", show);

  function show(event){
    if(event.target.parentElement.tagName === "LI"){
      // console.log(event.target.parentElement.dataset); // 获取HTML元素中以data-开头的属性
      let num = event.target.parentElement.dataset.number;
      opacity.querySelector("p").innerHTML = `关注人数 ${num}万`
      event.target.parentElement.appendChild(opacity);
    }
  }

</script>
</body>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值