如何通过shadow DOM访问light DOM中slot内的特定html标签?

问题描述 投票:0回答:2

我创建了一个自定义元素并在 html 中定义它,如下所示: `

<header>
    <custom-navbar links="[{title:'home'},{title:'About'}]" class="bg-purple">
        <h1 slot="logo">
            Amazon
        </h1>
    
        <navbar  slot="link" class="navbar-wrapper">
            <ul  class="link-container">
               
            </ul>
        </navbar>
    </custom-navbar>
</header>

`

我定义了我的自定义元素,如下所示:

class CustomNavbar extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.innerHTML = `
    
        <style>
           :host(.bg-purple){
                display:flex;
                width:100%;
                background-color:purple !important;
           
            }

            .container{
                display:flex;
                flex-direction:row;
                margin:1rem;
                align-items:center;
            
            }
   
        </style>

        <div class='container'>
                <div>
                    <slot name="logo"></slot>
                </div>
                <slot name='link'></slot>
        </div>
    
    
    `;
    }

     connectedCallback() {
       this._links = this.getAttribute("links");
   
        }
    }

    customElements.define("custom-navbar", CustomNavbar);


我正在寻找在 Shadow DOM 中获取 light DOM 中定义的 links 属性并将链接添加到 ul 元素?我还在

document.querySelector("custom-navbar").querySelector("ul")
内部使用了 :
connectedCallback()
,但它无法正常工作。

javascript web-component shadow-dom
2个回答
0
投票

尝试此代码,它通过使用自定义元素的 HTML 中提供的 links 属性在影子 DOM 中动态创建并填充链接列表。

class CustomNavbar extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.innerHTML = `
      <style>:host(.bg-purple){display:flex;width:100%;background-color:purple!important;}.container{display:flex;flex-direction:row;margin:1rem;align-items:center;}</style>
      <div class='container'><div><slot name="logo"></slot></div><slot name='link'></slot></div>
    `;
  }

  connectedCallback() {
    const links = JSON.parse(this.getAttribute("links") || '[]');
    const ulElement = this.shadowRoot.querySelector("ul.link-container");
    
    links.forEach(linkInfo => {
      const liElement = document.createElement("li");
      liElement.textContent = linkInfo.title;
      ulElement.appendChild(liElement);
    });
  }
}

customElements.define("custom-navbar", CustomNavbar);

希望它有效:)


0
投票

connectedCallback
opening 标签上触发;所以现阶段还没有 解析的 lightDOM
(除非CE是在DOM解析之后定义的)

所以你要么:

  • setTimeout

     中使用 
    connectedCallback
     来推迟在 lightDOM 中查询 
    <ul>
     标签

  • 在组件上添加一个

    insertLI

     方法来检查/等待 
    <ul>
     存在

setTimeout

是完全有效的,除非你有一个非常大的lightDOM(比如> 750个DOM节点)然后添加
HTML解析元素代码

注:

super(); this.attachShadow({ mode: "open" }); this.shadowRoot.innerHTML = `...`
可以链接到:

super() // sets AND returns 'this' scope .attachShadow({ mode: "open" }) // sets AND returns this.shadowRoot .innerHTML = `...`
    
© www.soinside.com 2019 - 2024. All rights reserved.