【问题标题】:How to uniquely identify DOM elements while using little size for the identifier如何在使用小尺寸标识符的同时唯一标识 DOM 元素
【发布时间】:2021-01-22 16:39:00
【问题描述】:

我正在做一个项目,其中两个浏览器应该同步它们的 DOM 元素。每当一个浏览器上的 DOM 元素发生变化时,只有被更改元素的变化和位置会通过 websocket 发送到另一个浏览器。

为了使其工作,我需要一种方法为更改的元素提供一个唯一标识符,该标识符使用少量大小,而其他浏览器应该能够定位更改元素的位置。

对此有什么好的方法?

【问题讨论】:

  • 这就是 HTML id attribute 的真正用途。它唯一标识 DOM 树中的单个元素节点,无需使用 CSS 选择器或旧的 xpath 概念。

标签: javascript html dom uniqueidentifier


【解决方案1】:

要将单向 DOM-1 复制到 DOM-2,您可以在 DOM-1 中使用 document MutationObserver,它会通知您:

  • 每个节点的属性更改
  • 已删除的节点
  • 已添加的节点
  • 已移动的节点,通过组合先前通知的顺序

如果 DOM-1 和 DOM-2 从一开始就相同,那么在 DOM-1 中唯一映射节点并在 DOM-2 中寻址的简单方法如下:

const {indexOf} = [];
const nodePath = node => {
  const path = [];
  let parentElement;
  // crawl up to the document.documentElement
  while (parentElement = node.parentElement) {
    path.push(indexOf.call(parentElement.childNodes, node));
    node = parentElement;
  }
  return path;
};

const findNode = path => path.reduceRight(
  // crawl down from the document.documentElement
  (parentElement, i) => parentElement.childNodes[i],
  document.documentElement
);

在 DOM-1 中,您可以通过 const path = nodePath(anyNode) 找到它,您可以通过 findNode(path) 在 DOM-2 中找到它。

然而,突变观察者不会告诉你的是,只要它的记录填充removedNodes 列表,就是这些节点已从中删除。 p>

为了规避这个限制,您需要在 DOM-1 中,并且可能通过 WeakMap 存储文档中附加的所有节点,以便您始终可以将更改传播到 DOM- 2.

// the most top script on the page (at least in DOM-1)
const paths = new WeakMap;
new MutationObserver(records => {
  for (const record of records) {
    for (const node of record.addedNodes)
      paths.set(node, nodePath(node));
  }
}).observe(document, {childList: true, subtree: true});

现在,每当 other 泛型 MutationObserver 负责通知,通过 Web 套接字或其他任何东西,DOM-2 进行更改时,您需要通知操作类型,可以是attributeinsertedremoved,对于removed的情况,您可以立即发送要抓取的路径,在这种情况下为paths.get(node)

我希望这些细节有用,因为您尝试做的事情很复杂,但并非不可能,而且我不会为您编写整个软件,因为这不是本网站的目的?

P.S. 具有字面上的 所有 节点路径,您可能还希望在 record.addedNodes 中递归设置这些路径,以便每个添加的节点,您需要抓取它的所有childNodes 并这样做直到所有childNodes 都被映射。这不会很快,但它会让您能够通知页面上的每个通用节点。

【讨论】:

  • 哇。谢谢你。这正是我一直在寻找的。一个非常详细的答案,我从中学到了很多东西。 ?
猜你喜欢
  • 1970-01-01
  • 2023-03-17
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 2019-03-26
  • 2020-03-25
  • 1970-01-01
  • 2011-08-25
相关资源
最近更新 更多