快速搞定前端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来判断是否触发元素

五、小结

  1. 事件绑定
  2. 事件冒泡
  3. 事件代理
  4. 通用事件绑定函数
发布了26 篇原创文章 · 获赞 6 · 访问量 1384

猜你喜欢

转载自blog.csdn.net/Sabrina_cc/article/details/105552987