如何克隆ShadowRoot? [英] How can I clone a ShadowRoot?

查看:68
本文介绍了如何克隆ShadowRoot?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试克隆一个影子根,以便可以将< content></content> 的实例与其对应的分布式节点交换.

I'm trying to clone a shadow root, so that I may swap instances of <content></content> with their corresponding distributed nodes.

我的方法:

var shadowHost = document.createElement('div');
var shadowRoot = shadowHost.createShadowRoot();

var clonedShadowRoot = shadowRoot.cloneNode(true);

不起作用,因为"ShadowRoot节点不可克隆".

does not work, as "ShadowRoot nodes are not clonable."

这样做的动机是希望检索组成的阴影树,以便可以使用渲染的HTML标记.

The motivation for this is that I wish to retrieve the composed shadow tree, so that I may use the rendered HTML markup.

由于Shadow DOM的性质,这可能无法正常工作,克隆过程可能会破坏对分布式节点的引用.

This may not work due to the nature of the Shadow DOM, the reference to the distributed nodes is likely to be broken by the cloning process.

组成阴影树可能是本机功能,但是在搜索w3c规范后,我找不到这种方法.

Composing the shadow tree is likely to be a native feature, but having searched through the w3c spec, I was unable to find such a method.

有这样的本机方法吗?否则,手动遍历(在过程中复制树)会起作用吗?

Is there such a native method? Or, failing that, would manual traversal (replicating the tree in the process), work?

推荐答案

如果您尝试深克隆可能包含一个或多个嵌套影子树的节点,则需要从该节点遍历DOM树并检查一路走来的影子根.如果对先前的答案有兴趣,请参阅编辑历史记录,该答案暗示了浅克隆方法的缺陷.

If you are trying to deep clone a node that may contain one or more nested shadow trees, then you will need to walk the DOM tree from that node and check for shadow roots along the way. See edit history if interested in the previous answer that suggested a flawed approach to shallow cloning.

const deepClone = (node) => {
  const clone = (n, p) => {
    const walk = (nextn, nextp) => {
      while (nextn) {
        clone(nextn, nextp);
        nextn = nextn.nextSibling;
      }
    }
    
    let c = n.cloneNode();
    p.appendChild(c);
    if (n.shadowRoot) {
      walk(n.shadowRoot.firstChild, c.attachShadow({ mode: 'open' }));
    }
  
    walk(n.firstChild, c);   
  }
  
  const fragment = document.createDocumentFragment();
  clone(node, fragment);
  return fragment;
}

// Example use of deepClone...

// create shadow host with nested shadow roots for demo
const shadowHost = () => {
  let host = document.createElement('div');
  let nestedhost = document.createElement('p');
  nestedhost.attachShadow({mode: 'open'}).appendChild(document.createElement('span'));
  host.attachShadow({mode: 'open'}).appendChild(nestedhost);
  return host;
}

// return fragment containing deep cloned node
let fragment = deepClone(shadowHost());
// deep cloned node
console.log(fragment.firstChild); 
// shadow tree node
console.log(fragment.firstChild.shadowRoot.firstChild);
// nested shadow tree node
console.log(fragment.firstChild.shadowRoot.firstChild.shadowRoot.firstChild);

这篇关于如何克隆ShadowRoot?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆