Как преобразовать HTML поддерево в строковые и встроенные стили, используя getComputedStyle? - PullRequest
1 голос
/ 10 марта 2020

Мне нужно преобразовать часть веб-сайта в строку html со встроенным CSS, сгенерированным из getComputedStyle.

Идея состоит в том, чтобы преобразовать все вложенные и плоские элементы в строку со встроенными стилями. Вывод может быть вставлен в. 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));

Но, похоже, он пропускает все элементы, у которых есть дети , Эти родительские теги (и их стили) не отображаются в окончательной строке.

Что можно изменить, чтобы эти родительские элементы также были включены? Или как еще я могу это сделать?

Вот пример:

Пример пера

Ответы [ 2 ]

0 голосов
/ 11 марта 2020

Мне удалось это исправить, установив внутренний HTML родительского узла в строку, зацикливая дочерние узлы вместо дочерних, и обрабатывая текстовые узлы.

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

0 голосов
/ 11 марта 2020

Я заставил ваш пример работать, получив outerHTML узла root и используя свойство stylesheets для получения стилей:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...