如何获取一个div元素及其所有子元素的计算样式?

3

我想要获取HTML元素及其所有计算样式。

当HTML元素没有子元素时,我已经成功实现了这个功能,但如果HTML元素有许多子元素,我该如何获取每个子元素的所有计算样式?

以下是我目前拥有的:

  • 用户点击HTML元素后,我使用event.target.cloneNode(true)获取HTML元素
  • 然后我为克隆的元素设置一个ID
  • 我获取计算样式
  • 然后将样式添加到我的克隆元素中
  private onClickHtmlCssGrabber = (event) => {
      // clone the html element
      let clickedHtmlElement = event.target.cloneNode(true)

      // set an id to the cloned element
      clickedHtmlElement.setAttribute('id', 'clonedElement')

      // get the computed style of the element
      let clikedHtmlElementStyle =  getComputedStyle(event.target).cssText

      // set the style on my newly cloned element
      clickedHtmlElement.style.cssText = clikedHtmlElementStyle
  }

所以基本上,此时我最终得到的东西类似于:
<div id="clonedElement" style="... all the coputedStyle">Example text</div>

但当我想要提取的HTML元素有很多子元素时,我的问题就出现了:

<div class="style1">
  <div class="style-child-1">
    <div class="style-child-2">
      example text child 2
    <div>
    <div class="style-child-3">
      example text child 3
    </div>
  <div>
</div>

那么我如何提取整个带有其子元素及其样式的HTML元素?


1
还没有使用过,但是你应该能够通过TreeWalker(https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker)“遍历”你的元素和子元素。你可能需要使用`TreeWalker.nextNode()`,然后逐个提取样式,并在遍历时创建克隆。 - Alex Berger
1
嘿,这个特定的讨论可能会帮助您获得一些见解 - https://dev59.com/MHI-5IYBdhLWcg3wc3-w#1848489 - Lakshya Thakur
1个回答

1

我自己也很好奇,因此创建了一个快速示例来演示一个元素。即使没有子元素,也应该可以正常工作,因为循环将不会运行。

// container where we want to put the clone
const targetContainer = document.querySelector('.target');

// your element that you want to clone
const root = document.querySelector('.style1');
const rootWalker = document.createTreeWalker(
    root,
    NodeFilter.SHOW_ELEMENT,
    { acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; } }
);

// now clone the element and also creat a walker for it
const rootClone = root.cloneNode(true);
const cloneWalker = document.createTreeWalker(
    rootClone,
    NodeFilter.SHOW_ELEMENT,
    { acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; }}
);

// clone styles for the root element itself
rootClone.style.cssText = getComputedStyle(root).cssText
rootClone.className = '' // simply clearing it to see if styles are copied

// get the first child node, if there is no child, .nextNode() will return null
let nextRootNode = rootWalker.nextNode();
let nextCloneNode = cloneWalker.nextNode();

// now if we have a child node, the loop is running
while (nextRootNode !== null) {
  // get styles from original to clone
    nextCloneNode.style.cssText = getComputedStyle(nextRootNode).cssText;
  nextCloneNode.className = '' // again removing classes for demonstration
  
  // get next node, again if there are no more, null will be returned and loop will stop
  nextRootNode = rootWalker.nextNode();
  nextCloneNode = cloneWalker.nextNode();
}

// simply append the cloned node to your desired target
targetContainer.append(rootClone);
.style1 {
  background: yellow;
  padding: 10px;
  margin: 5px 0;
}

.style-child-1 {
  background: green;
  padding: 10px;
}

.style-child-2 {
  color: blue;
}

.style-child-3 {
  color: orange;
  text-transform: uppercase;
}
<div class="style1">
  <div class="style-child-1">
    <div class="style-child-2">
      example text child 2
    </div>
    <div class="style-child-3">
      example text child 3
    </div>
   </div>
</div>

<div class="target">

</div>

如果您愿意,可以获取此内容并根据自己的需求进行调整。例如,创建一个函数并在单击时运行它。

1
太好了,这正是我需要的。我编辑了你的答案,并移除了document.createTreeWalker()的第四个参数false,因为经过一些研究,它已经被弃用了。在修改被接受后,我会接受这个答案。谢谢。 - AziCode
1
我再次检查了一遍,你是完全正确的,它已经被弃用了。我从我的答案中将其删除。 - Alex Berger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接