第8章 JS-Web-API-事件【事件不会,基本等于半残废,必考!必考!】

返回章节目录

目录

1.事件绑定和事件冒泡

事件绑定

事件冒泡

2.事件代理


1.事件绑定和事件冒泡

事件绑定

event.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>事件 演示</title>
        <style>
            div {
                border: 1px solid #ccc;
                margin: 10px 0;
                padding: 0 10px;
            }
        </style>
    </head>
    <body>
        <button id="btn1">一个按钮</button>

        <script src="./event.js"></script>
    </body>
</html>

event.js

// 事件绑定函数
function bindEvent(elem, type, fn) {
    elem.addEventListener(type, fn)
}

const btn1 = document.getElementById('btn1')
bindEvent(btn1, 'click', event=>{
    console.log(event.target) // event.target就是触发点击的元素,这里就是btn1
    event.preventDefault() // 阻止默认行为,如果这里是<a>标签,阻止默认跳转
    alert('clicked')
})

运行结果

事件冒泡

事件冒泡的应用场景就是事件代理,我们后面再说

代码演示:

event.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>事件 演示</title>
        <style>
            div {
                border: 1px solid #ccc;
                margin: 10px 0;
                padding: 0 10px;
            }
        </style>
    </head>
    <body>
        <button id="btn1">一个按钮</button>

        <div id="div1">
            <p id="p1">激活</p>
            <p id="p2">取消</p>
            <p id="p3">取消</p>
            <p id="p4">取消</p>
        </div>
        <div id="div2">
            <p id="p5">取消</p>
            <p id="p6">取消</p>
        </div>

        <script src="./event.js"></script>
    </body>
</html>

event.js

// 事件绑定函数
function bindEvent(elem, type, fn) {
    elem.addEventListener(type, fn)
}

const p1 = document.getElementById('p1')
bindEvent(p1, 'click', event => {
    // event.stopPropagation() // 阻止冒泡
    console.log('激活')
})
const body = document.body
bindEvent(body, 'click', event => {
    console.log('取消')
    // console.log(event.target)
})

event.stopPropagation() // 阻止冒泡,我们先把这一句注释掉看一下

运行结果

结果发现冒泡了,我点击激活的时候也触发了body的监听事件打印取消,该如何取消冒泡呢??

event.stopPropagation() // 阻止冒泡

取消上面event.js的这句注释,我们再来演示一下

这样就好了

2.事件代理

事件代理也叫事件委托,事件代理是基于事件冒泡的机制的

这篇文章写的事件代理的解释很通俗易懂:简述JS中的事件委托和事件代理

当不方便去一个一个循环绑定监听的时候就直接绑定它的父元素,最后再判断是不是想要的元素,再做其他的逻辑,这样的特点就是不用每个加监听,后续新增的子元素自动就有了父元素的监听,非常方便。

事件代理就会让代码看起来简洁,并且会减少浏览器的内存,毕竟每个元素加一个监听耗费内存,但是不要滥用,比如明明只有一个元素去监听,非要用事件代理就太勉强了

event.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>事件 演示</title>
        <style>
            div {
                border: 1px solid #ccc;
                margin: 10px 0;
                padding: 0 10px;
            }
        </style>
    </head>
    <body>
        <button id="btn1">一个按钮</button>

        <div id="div3">
            <a href="#">a1</a><br>
            <a href="#">a2</a><br>
            <a href="#">a3</a><br>
            <a href="#">a4</a><br>
            <button>加载更多...</button>
        </div>

        <script src="./event.js"></script>
    </body>
</html>

event.js

// 通用的事件绑定函数,支持普通的监听和代理监听
function bindEvent(elem, type, selector, fn) {
    if (fn == null) { // 三个参数和四个参数的判断处理
        fn = selector;
        selector = null;
    }
    elem.addEventListener(type, event=>{
        const target = event.target;
        if (selector) {
            // 有selector就是代理
            if (target.matches(selector)) {
                fn.call(target, event);
            }
        } else {
            fn.call(target, event);
        }
    });
}


// 普通绑定
const btn1 = document.getElementById('btn1')
bindEvent(btn1, 'click', event=>{
    console.log(event.target)
    alert('clicked') // 这里如果写this就不是和下面一样了,因为箭头函数this是父作用域的this,这里是window
})

// 代理绑定
const div3 = document.getElementById('div3')
bindEvent(div3, 'click', 'a', function (event) {
    event.preventDefault()
    alert(this.innerHTML) // 这里可以写this是因为bindEvent里面的fn.call(target, event),绑定了点击的target是<a>标签
})

// 如果是箭头函数
/*
bindEvent(div3, 'click', 'a', event=> {
    event.preventDefault()
    alert(event.target.innerHTML)
})
*/

运行结果

这里加载更多按钮没有添加逻辑,主要是为了告诉大家,这里如果再新增<a>标签,都会有绑定监听事件,因为父元素div绑定了监听,这也是事件的冒泡机制

这里的 button 和 a 都是绑定通用函数bindEvent,event.target是获取触发的元素,matches判断是否是触发元素

关注、留言,我们一起学习。

===============Talk is cheap, show me the code================

发布了224 篇原创文章 · 获赞 983 · 访问量 91万+

猜你喜欢

转载自blog.csdn.net/qq_34115899/article/details/104131591