DOM如何区分内容与属性完全相同的页面元素?
DOM如何区分页面上内容、属性完全相同的元素
以下是问题对应的示例代码:
import * as React from "react"; import Box from "@mui/material/Box"; import Popper from "@mui/material/Popper"; export default function SimplePopper() { const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null); console.log(anchorEl); const handleClick = (event: React.MouseEvent<HTMLElement>) => { setAnchorEl(anchorEl ? null : event.currentTarget); }; const open = Boolean(anchorEl); const id = open ? "simple-popper" : undefined; return ( <div> {/* button 1 */} <button type="button" onClick={handleClick}> Toggle Popper </button> {/* button 2 */} <button type="button" onClick={handleClick}> Toggle Popper </button> <Popper id={id} open={open} anchorEl={anchorEl}> <Box sx={{ border: 1, p: 1, bgcolor: "background.paper" }}> The content of the Popper. </Box> </Popper> </div> ); }
你看到两个按钮打印结果一致,本质是对控制台DOM展示逻辑的误解:
控制台输出的
<button type="button">Toggle Popper</button>只是DOM元素对外展示的HTML字符串快照,不是元素本身的身份标识。
DOM区分元素从来不是靠标签文本、class、id这类外在属性:
- 浏览器解析HTML生成DOM树时,每个节点都是独立存在的JavaScript宿主对象,在内存中占据完全不同的堆地址,是互不影响的独立实例。哪怕两个节点的所有HTML属性、文本内容完全一模一样,用
===做相等判断也会返回false。 - 点击事件触发时,
event.currentTarget拿到的是触发当前事件的元素对象的直接引用,不是元素的字符串拷贝。你把这个引用存到anchorEl状态里,MUI的Popper组件会直接读取这个引用指向的元素的位置、尺寸信息做定位,自然能精准对齐到你实际点击的按钮。
你可以自己加一行代码验证这个逻辑:
const handleClick = (event: React.MouseEvent<HTMLElement>) => { // 对比当前点击的元素和之前存的anchorEl是不是同一个 console.log('是否为同一个元素对象:', event.currentTarget === anchorEl); setAnchorEl(anchorEl ? null : event.currentTarget); };
交替点击两个按钮你会发现,每次切换点击的按钮时,相等判断都会返回false——两个按钮从根上就是完全独立的两个对象,只是序列化后的HTML字符串长得一样而已。你在控制台点开打印的DOM元素详情,也能看到二者在DOM树中的位置、内置属性都是完全独立的,修改其中一个的样式、属性不会对另一个产生任何影响。
内容的提问来源于stack exchange,提问作者TareTor
相关产品推荐
相关产品推荐

