javascript - 是否可以在不使用 `<template>` 和模板槽的情况下在自定义元素中添加元素?

标签 javascript html dom shadow-dom

我正在尝试创建一个可以采用其他 HTML 元素的自定义组件,但是,它必须灵活,不必使用 <template>每次使用该组件时,都会在 HTML 文件中插入模板。已经尝试在每次渲染后使用 const children = this.shadow.querySelectorAll('.menu > *') 进行查询connectedCallback()内函数,但结果是空 NodeList

class SideMenu extends HTMLElement {
    constructor() {
        super();
        this.shadow = this.attachShadow({mode:'open'});
    }

    render() {
        this.shadow.innerHTML = `
        <style>
          .menu {
            display: flex;
            flex-direction: column;
            height: 100vh;
            padding: 2em;
            width: 33vw;
            gap: 10px;
            background-color: #2C2B2B;
          }
        </style>
        <div class="menu">
        </div>
        `;
    }

    connectedCallback() {
        this.render();
    }
}

customElements.define('side-menu', SideMenu);
<side-menu>
    <div>Element1</div>
    <div>Element2</div>
    <div>Element3</div>
    <div>ElementN</div>
</side-menu>

基本上,自定义元素必须能够包含任意数量的元素,例如无序列表 ( <ul> ),它可以包含多个 <li>里面。

最佳答案

  • 您有一个 ShadowDOM,因此当您使用 :host 设置组件样式时不需要额外的 div

  • 您可以手动将ligthDOM元素移动到shadowDOM

  • super() 设置并返回“this”范围

  • attachShadow 设置并返回 this.shadowRoot

  • append 在 Internet Explorer 中不可用(“老式”开发人员仍然使用 appendChild)
    请注意,它将 DOM 元素从 lightDOM 移动到 ShadowDOM。如果您移动 Web 组件,connectedCallback再次运行(但 lightDOM 将为空),因此知道您在 connectedCallback

    中做了什么

customElements.define('side-menu', class extends HTMLElement {
    constructor() {
        super().attachShadow({mode:'open'}).innerHTML = `
        <style>
          :host {
            display: flex; flex-direction: column; gap: 10px;
            height: 100vh; width: 33vw;
            padding: 2em;
            background-color: #2C2B2B; color: gold;
          }
        </style>`;
    }

    connectedCallback() {
        this.shadowRoot.append(...this.children);
    }
});
<side-menu>
    <div>Element1</div>
    <div>Element2</div>
    <div>Element3</div>
    <div>ElementN</div>
</side-menu>

关于javascript - 是否可以在不使用 `<template>` 和模板槽的情况下在自定义元素中添加元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73430896/

相关文章:

javascript - 使用 jquery 查找具有特定 id 值的子元素

html - 在所有页面上显示边栏上的编辑

javascript - 如何使链接在未滚动时保持样式?

javascript - 如何在一行中将 child 附加到一个 div 中

javascript - 为什么 NodeList[0] 和 node = NodeList[0] 的行为不同?

javascript - 当鼠标移到该选项上时如何获取要选择的多选对象的选项

javascript - if 语句中的函数仅在第一次时未定义,但在休息时间函数调用也未定义

javascript - 将工厂与 ng 模块绑定(bind)是一种好习惯吗?

javascript - return语句是从内到外工作的吗?

python - 在 Pelican 静态网站中托管原始 HTML 页面