快速搞定前端JS面试 -- 第八章JS-Web-API-事件(事件绑定、事件冒泡、事件代理)

第八章JS-Web-API-事件

一、事件绑定

二、事件冒泡

三、事件代理

1. 场景:瀑布流

2. 例子描述

3. 事件代理的优点

4. 通用的事件绑定函数

四、问题解答

1. 编写一个通用的事件监听函数?

2. 描述事件冒泡的流程?

3. 无限下拉的图片列表,如何监听每个图片的点击?


题目

  1. 编写一个通用的事件监听函数
  2. 描述事件冒泡的流程
  3. 无限下拉的图片列表,如何监听每个图片的点击?

知识点

  1. 事件绑定
  2. 事件冒泡
  3. 事件代理

一、事件绑定

通用的事件绑定函数
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)
})
const div2 = document.getElementById('div2')
bindEvent(div2, 'click', event => {
    console.log('div2 clicked')
    console.log(event.target)
})

获取触发元素: event.target输出事件是由哪个元素触发的

二、事件冒泡

功能:激活/取消状态切换(将取消事件绑定在body上,将激活事件绑定在p1上)

对于嵌套事件输出的先后顺序:冒泡,顺着DOM 结构向上级冒泡

如果不阻止事件冒泡,则,点击p1会输出:激活 取消(冒泡到body输出的取消)

阻止冒泡:stopPropagation()

 <body>
        <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>

三、事件代理

事件代理是在事件冒泡的机制下进行的

1. 场景:瀑布流

2. 例子描述

点击增加a标签,并且可以通过各种方式无限加载,因此div中不知道会有多少个a标签,无法一个一个绑定事件,因此这时候就可以把事件绑定到div上,当点击a标签时,会通过冒泡机制到div,再通过一些方法拿到a标签。即当数量比较多或者比较复杂,无法绑定事件时,可以将事件绑定到他的父元素上。

<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>
// 代理绑定
const div3 = document.getElementById('div3')
bindEvent(div3, 'click', event => {
    event.preventDefault()    // 阻止默认行为(页面页面调转)
    const target = event.targrt
    if (target.nodeNamr === 'A') {
        alert(target.innerHTML)
    }
})

阻止默认行为:event.preventDefault()

3. 事件代理的优点

  1. 代码简介;(如果分析每个a标签,结构就比较复杂,要进行循环)
  2. 减少浏览器内存使用;(如果含有a标签比较多,每个都绑定一个事件监听,耗内存)

(但是不要滥用)

4. 通用的事件绑定函数

要求:能支持普通的监听,也能支持代理情况的监听

function bindEvent(elem, type, selector, fn) {  // selector是个css选择器
    if (fn == null) {   // 判断只传入三个参数
        fn = selector   
        selector = null
    }
    elem.addEventListener(type, event => {
        const target = event.target    
        if (selector) {
            // 有selector时是代理绑定
            if (target.matches(selector)) {  // 判断DOM元素是否符合css选择器
                fn.call(target, event)
            }
        } else {
            // selector为空,只有三个参数,是普通绑定
            fn.call(target, event)
        }
    })
}

// 普通绑定
const btn1 = document.getElementById('btn1')
bindEvent(btn1, 'click', function (event) {    // 注意不能使用箭头函数,否则获取的是上级window
    // console.log(event.target) // 获取触发的元素
    event.preventDefault() 
    alert(this.innerHTML)     // this
})

// 代理绑定
const div3 = document.getElementById('div3')
bindEvent(div3, 'click', 'a', function (event) {
    event.preventDefault()    // 阻止默认行为(页面页面调转)
    alert(this.innerHTML)    // 如果使用箭头函数的写法 event.target.innerHTML
})

四、问题解答

1. 编写一个通用的事件监听函数?

   需要考虑:普通绑定 代理绑定

2. 描述事件冒泡的流程?

    数据冒泡是基于DOM树形结构;

    时间会顺着触发元素往上冒泡

    应用场景:代理

3. 无限下拉的图片列表,如何监听每个图片的点击?

   事件代理

   使用event.target获取触发元素

   用matches来判断是否触发元素

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白Rachel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值