You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:45:41