我有一个包含一个或多个<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));
答案 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循环,它会追加而不会每次都替换。
我希望有一天意大利面可以帮助别人。
如果有人可以解释这个行为,或者确认错误,请告诉我,我会提交。