Как удалить shadow root из HTML-элемента, украшенного shadow DOM из шаблона? [web-компонентов]

Я изучаю импорт, шаблоны, shadow DOM и пользовательские элементы в Chrome Canary (33.0.1712.3). В макете сетки у меня есть определенный элемент содержимого (область отображения), который будет отображать различные веб-компоненты или клонированные фрагменты light DOM, импортированные из файлов. Однако я не могу переопределить обычный HTML DOM после добавления shadow DOM, потому что я не знаю, как удалить shadow root. После создания теневой корень остается и мешает визуализации обычный дом. (Я просмотрел различные спецификации W3C, такие как введение в веб-компоненты, shadow DOM, шаблоны, статьи Бидельмана о HTML5 Rocks и т. д.) Я выделил проблему в простом примере ниже:

нажмите "Показать обычный старый div"; нажмите" Показать затененный шаблон"; нажмите"Показать простой старый div". Проверьте в devtools после каждого щелчка. После третьего щелчка нет выхода под кнопками и в devtools я вижу:

<div id="content">
  #document-fragment
  <div id="plaindiv">Plain old div</div>
</div>

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

removing_shadows.HTML-код

    <!DOCTYPE html>
<html lang="en">

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>

  <template id="shadowedTemplateComponent">
    <style>
      div { background: lightgray; }
      #t { color: red; }
    </style>

    <div id="t">template</div>

    <script>console.log("Activated the shadowed template component.");</script>
  </template>

  <template id="plainDiv">
    <div id="plaindiv">Plain old div</div>
  </template>
</head>

<body>
<div>
  <input type="button" value="show plain old div" onclick="showPlainOldDiv()"/>
  <input type="button" value="show shadowed template" onclick="showShadowTemplate()"/>
  <div id="content"></div>
</div>

<script>
  function removeChildren(elt) {
    console.log('removing children: %s', elt);
    while (elt.firstChild) {
      elt.removeChild(elt.firstChild);
    }
  }
  function removeShadow(elt) {
    if (elt.shadowRoot) {
      console.log('removing shadow: %s', elt);
      removeChildren(elt.shadowRoot); // Leaves the shadow root property.
      // elt.shadowRoot = null; doesn't work
      // delete elt.shadowRoot; doesn't work
      // What goes here to delete the shadow root (#document-fragment in devtools)?
    }
  }

  function showPlainOldDiv() {
    console.log('adding a plain old div');
    var host = document.querySelector('#content');
    removeChildren(host);
    removeShadow(host);
    var template = document.querySelector('#plainDiv');
    host.appendChild(template.content.cloneNode(true));
  }

  function showShadowTemplate() {
    console.log('adding shadowed template component');
    var host = document.querySelector('#content');
    removeChildren(host);
    removeShadow(host);
    var template = document.querySelector('#shadowedTemplateComponent');
    var root = host.shadowRoot || host.webkitCreateShadowRoot();
    root.appendChild(template.content.cloneNode(true));
  }
</script>
</body>
</html>

2 ответов


вы не можете удалить теневой корень после его добавления. Однако, вы можете заменить его на новый.

Как упоминалось здесь,http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-301/, новейший теневой корень "выигрывает" и становится отображаемым корнем.

вы можете заменить свой теневой корень новым теневым корнем, который содержит только <content> псевдо-элемент для вставки всего из светового DOM обратно в теневой DOM. В этот момент, как насколько я знаю, это будет функционально эквивалентно отсутствию теневого дома вообще.


спецификация Shadow DOM переместилась с v0 на v1.

одно из изменений заключается в том, что в v1 нет способа создать теневой корень на себе, и элемент host может содержать только один теневой корень.

таким образом, кажется, что ответ на замену теневого корня новым пустым теневым корнем больше не действителен.