当逐个给每个li绑定监听事件,当li太多之后,需要绑定很多监听器,(未清除监听事件)可能会导致内存泄漏,也让代码变得复杂。所以我们可以只给ul标签绑定监听事件,点击li会通过冒泡触发ul的click事件,然后也可以实现。
实现:
import React from 'react'; import { useEffect } from 'react';import './css/index.css';function App() { const list = [ { id: "10002", name: 'book1' }, { id: "10003", name: 'book2' }, { id: "10004", name: 'book3' } ] function liClickHandle(event) { event = event || window.event; var target = event.target || event.srcElement; console.log(target.id); switch (target.id) { case "10002": console.log(target) break; case "10003": console.log(target) break; case "10004": console.log(target) break; default: console.log("error") } } useEffect(() => { var ul = document.getElementById("ulid"); ul.addEventListener('click', liClickHandle, false); return () => { ul.removeEventListener('click', liClickHandle, false); }; }, []) return ( <div className="App"> <ul id="ulid"> { list.map((item, index) => { return (<li id={item.id} key={item.id}>{item.name}</li>) }) } </ul> </div> );}export default App;
监听事件:
addEventListener(event, function, useCapture);
- 第一个参数是事件的类型(比如 "click" 或 "mousedown")。
- 第二个参数是当事件发生时我们需要调用的函数。
- 第三个参数是布尔值,指定使用事件冒泡还是事件捕获。此参数是可选的。
useCapture默认值是 false,将使用冒泡传播,如果该值设置为 true,则事件使用捕获传播。
在 HTML DOM 中有两种事件传播的方法:冒泡和捕获。
事件传播是一种定义当发生事件时元素次序的方法。假如
元素内有一个
,然后用户点击了这个
元素,应该首先处理哪个元素“click”事件?
- 在冒泡中,最内侧元素的事件会首先被处理,然后是更外侧的:首先处理
元素的点击事件,然后是
元素的点击事件。 - 在捕获中,最外侧元素的事件会首先被处理,然后是更内侧的:首先处理 元素的点击事件,然后是
元素的点击事件。