$()。html附加到shadow DOM而不是replace

时间:2016-02-17 22:06:58

标签: jquery shadow-dom

我有一个包含一个或多个<article>的网页,每个网页都包含一个<nav>和一个<section class='app-content'>托管影子DOM。我想在用户点击<section>中的元素时以编程方式将多个模板中的一个加载到<nav>

我这里有一个辅助函数,它应该点击<nav>的被点击的子项并找到关联的<section>,然后创建或获取对shadow DOM的引用,清除内容,然后插入模板的内容。

  //maps menu event to content container
  //loads one of several templates, replacing content
  function replaceShadowContent(nav_elem_clicked, content_to_load) {
    var $contentPane = $(nav_elem_clicked).parentsUntil('article').next();
    var shadowDOM;//$contentPane[0].shadowRoot;
    if (!!$contentPane[0].shadowRoot) {
      shadowDOM = $contentPane[0].shadowRoot;
    } else {
      console.log('make new shadow root');
      shadowDOM = $contentPane[0].createShadowRoot();
    }
    $(shadowDOM).html(document.importNode(document.getElementById(content_to_load).content, true));
  }

目前,模板仅包含<p>元素。

问题是,我最终在影子DOM rathar中列出了<p>个,而不是一次只有一个。{1}}。如果我使用.append()而不是.html(),它的行为完全相同。我试过没有jquery,只使用普通的DOM函数,我尝试了.empty().replaceWith()等的各种组合。

我使用的是最新版本的Chrome,仅使用jquery和本机API,没有其他库。

这是一个包含完整代码的jsbin:https://jsbin.com/fiwago/edit?html,output

有趣的是,当天早些时候的这个代码段工作正常,但是控制台发出警告,称呼createShadowRoot已被弃用。

      var $contentPane = $(this).parentsUntil('article').next();
      var shadowDOM = $contentPane[0].createShadowRoot();
      shadowDOM.appendChild(document.importNode(document.getElementById('simple-widget').content, true));

1 个答案:

答案 0 :(得分:1)

我最终通过在shadowDOM而不是jquery上使用原生JS来实现它。我不确定为什么会发生这种情况,我认为它对jquery来说是内部的,对于影子DOM并不完全满意,但我不知道。

以下是工作代码:

  //maps menu event to content container
  //loads one of several templates, replacing content
  function replaceShadowContent(nav_elem_clicked, content_to_load) {
    var $contentPane = $(nav_elem_clicked).parentsUntil('article').next();
    var shadowDOM;//$contentPane[0].shadowRoot;
    if (!!$contentPane[0].shadowRoot) {
      shadowDOM = $contentPane[0].shadowRoot;
    } else {
      shadowDOM = $contentPane[0].createShadowRoot();
    }
    while (shadowDOM.firstChild) {
      shadowDOM.removeChild(shadowDOM.firstChild);
    }
    shadowDOM.appendChild(document.importNode(
        document.getElementById(content_to_load).content, true)
    );
  }

我不得不使用jquery来选择正确的窗格,但这不适用于问题,我切换到if块内的常规DOM树。

棘手的是,当我尝试简单shadowDOM.removeChild(shadowDOM.firstChild)时,它引发了异常:firstChild未定义,无法移除。出于某种原因,在循环中检查firstChild可以解决问题,但是代码从不使用循环,我在那里扔了一个console.log,它从不打印。如果你注释掉while循环,它会追加而不会每次都替换。

我希望有一天意大利面可以帮助别人。

如果有人可以解释这个行为,或者确认错误,请告诉我,我会提交。