【问题标题】:$().html appends to shadow DOM instead of replace$().html 附加到影子 DOM 而不是替换
【发布时间】:2016-05-29 20:49:57
【问题描述】:

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

我这里有一个辅助函数,它应该获取<nav> 的点击子元素并找到关联的<section>,然后创建或获取对影子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> 元素。

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

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

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

有趣的是,当天早些时候的这个 sn-p 有效,但控制台大声疾呼称不推荐调用 createShadowRoot

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

【问题讨论】:

    标签: jquery shadow-dom


    【解决方案1】:

    我终于让它工作了,通过在shadowDOM 上使用原生 JS 而不是 jquery。我不确定为什么会发生这种情况,我认为它是 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 循环,它会追加而不是每次都替换。

    我希望有一天这个意大利面混乱对某人有所帮助。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-05
      • 1970-01-01
      • 1970-01-01
      • 2015-10-30
      • 2022-11-18
      • 2018-07-17
      • 1970-01-01
      相关资源
      最近更新 更多