【问题标题】:How to convert HTML subtree to string and inline styles using getComputedStyle?如何使用 getComputedStyle 将 HTML 子树转换为字符串和内联样式?
【发布时间】:2020-06-22 19:56:29
【问题描述】:

我需要将网站的一部分转换为带有从 getComputedStyle 生成的内联 CSS 的 html 字符串。

这个想法是将所有嵌套和平面元素转换为具有内联样式的字符串。输出可以粘贴到 .html 或在线代码编辑器中,并且看起来相同。它接近了,我已经修补了一个小时左右。

到目前为止,这是我的代码:

function loopThroughRoots(root) {
    let htmlString = "";
    let temp = root;

    console.log(root.tagName);

    temp.setAttribute(
        "style",
        window.getComputedStyle(root).cssText
    );

    if (temp.children.length > 0) {
        console.log("has children, looping");
        for (let i = 0; i < temp.children.length; i++) {
            htmlString += loopThroughRoots(temp.children[i]);
        }
    } else {
        console.log("no children, setting value");
        htmlString = temp.outerHTML;
    }

    return htmlString;
}

var root = document.querySelector("#markdown");
console.log(loopThroughRoots(root));

但它似乎错过了任何有孩子的元素。这些父标签(及其样式)不会出现在最终字符串中。

我可以进行哪些更改以使这些父元素也包含在内?或者我还能怎么做?

这是一个例子:

Example Pen

【问题讨论】:

  • 为什么不直接使用root.innerHTML 来获取html?
  • 我也需要计算样式作为内联样式
  • 您可以使用stylesheets property 获取样式并将它们粘贴到目标中的style 元素中。

标签: javascript css dom


【解决方案1】:

我通过获取根节点的 outerHTML 并使用 stylesheets property 获取样式来使您的示例工作:

document.getElementById('btn').onclick = () => {
  const styles = [...document.styleSheets]
    .map(sheet => [...sheet.rules]
      .map(rule => rule.cssText)
      .join(''))
    .join('');
  const markup = document.querySelector("#example").outerHTML;
  
  console.log(`<style>${styles}</style>${markup}`);
}
.example1 {
  margin-left:1rem;
}

h1 {
  font-size:3rem;
}

.black-background {
   background-color:black;
}

.color-white {
  color:white;
}

.padding-2 {
  padding:2rem;
}
<button id="btn">Log markup and style to console</button>

<div id="example" class='example1'>
  <h1>Test</h1>
  <blockquote class="black-background">
    <h3 class="color-white">Children work</h3>
    <p class="color-white">I will show up</p>
  </blockquote>
  <div class="padding-2">
    <p>My parent has children</p>
    <p>The parent doesn't show up in the string.</p>
   </div>                     
</div>

【讨论】:

  • 这对我不起作用,因为在尝试获取规则属性 (CORS) 时出现 Chrome 错误,并且因为它没有使用计算样式,所以我得到了不相关的 css 规则。但它确实在那支笔中起作用。
【解决方案2】:

我能够通过将父节点的 innerHTML 设置为字符串、循环子节点而不是子节点以及处理文本节点来修复它。

function loopThroughRoots(root) {
  let htmlString = "";
  let temp = root.cloneNode(true);

  //if text
  if (temp.nodeType == 3) {
    return temp.nodeValue;
  }

  //normal node with children
  if (temp.nodeType == 1) {
    if (temp.nodeType == 1 && temp.childNodes && temp.childNodes.length > 0) {
      for (let i = 0; i < temp.childNodes.length; i++) {
        htmlString += loopThroughRoots(temp.childNodes[i]);
      }
      temp.innerHTML = htmlString;
      temp.setAttribute("style", window.getComputedStyle(root).cssText);
      htmlString = temp.outerHTML;
    } else {
      //normal node, no children
      temp.setAttribute("style", window.getComputedStyle(root).cssText);
      htmlString = temp.outerHTML;
    }
  }
  return htmlString;
}

function runTest() {
  var root = document.querySelector("#example");
  console.log(loopThroughRoots(root));
}

演示:https://codepen.io/ethan-vernon/pen/OJVQxXL?editors=1010

【讨论】:

    猜你喜欢
    • 2014-12-07
    • 2015-11-16
    • 2021-08-23
    • 2011-01-15
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    相关资源
    最近更新 更多