使用 Bootstrap 设置自定义元素 ShadowDOM 样式不起作用

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

我尝试使用 ShadowDom 及其样式(即 bootsrap)创建自定义元素导航栏。我使用 NPM 安装了引导程序。然后我在 style.scss 中导入了 bootstrap 并从 bootstrap 中获取了 navbar 元素以应用于我的自定义元素,但在应用程序过程中我的 navbar 没有任何样式,这可能是由于 bootstrap 样式未能提前渗透到 ShadowDom 造成的,有人经历过吗???这是我的代码和文件结构我也使用 webpack 来捆绑它 Structure Folder

my style.scss

@import 'bootstrap/scss/bootstrap';
$bg : rgb(192, 253, 255);
body {
    background-color: $bg;
}
navbar.js
class NavBar extends HTMLElement {
    constructor() {
        super();
        this.shadowDOM = this.attachShadow({
            mode: 'open'
        });
    }

    connectedCallback() {
        this.render();
    }

    render() {
        this.shadowRoot.innerHTML = `
        <nav class="navbar navbar-expand-lg bg-body-tertiary">
            <div class="container-fluid">
                <a class="navbar-brand" href="#">Navbar</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarNav">
                    <ul class="navbar-nav">
                        <li class="nav-item">
                            <a class="nav-link active" aria-current="page" href="#">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Features</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Pricing</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link disabled" aria-disabled="true">Disabled</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        `;
    }

}

customElements.define("nav-bar", NavBar);
index.js

import * as bootstrap from 'bootstrap';
import css from './style/style.scss';
import './script/component/nav-bar.js';
import main from './script/view/main.js';

document.addEventListener('DOMContentLoaded', main);

我想使用这个 bootsrap 来使自定义元素样式处理过程更容易。

webpack web-component shadow-dom custom-element
1个回答
0
投票

页面中添加了引导样式,它不会穿透影子 DOM 边界(这是整个 Web 组件封装概念的一部分)。 要解决此问题,您需要将样式添加到自定义元素影子根中。有几个选择。一般来说,使用

<style>
元素并将其中的 css 添加到 ShadowRoots innerHTML 中是最简单的,但我假设您将拥有多个自定义元素并且引导 css 不小,这不是一种最佳性能明智的方法。 更好、更现代的方法是使用
adoptedStyleSheets
(现在所有主流浏览器都支持)。即

// assuming your webpack config will return this as a string and not load it  e.g. via css-loader
import * as bootstrap from 'bootstrap';

const bootstrapStyleSheet = new CSSStyleSheet();
bootstrapStyleSheet.replaceSync(bootstrap);


// later in each of your custom elements needing the bootstrap styling:
this.shadowRoot.adoptedStyleSheets.push(bootstrapStyleSheet);

如果您使用 webpack 的 css-loader,可以选择将其自动获取为 CSSStyleSheet。请参阅:https://webpack.js.org/loaders/css-loader/#exporttype

css-style-sheet

import sheet from "./styles.css" assert { type: "css" };

shadowRoot.adoptedStyleSheets = [sheet];

当然,你还需要将自己的 css 加载到影子 DOM 中。你可以在哪里做同样的事情并通过

添加它
shadowRoot.adoptedStyleSheets = [bootstrapStyleSheet, componentCss];
// or 
shadowRoot.adoptedStyleSheets.push(bootstrapStyleSheet);
shadowRoot.adoptedStyleSheets.push(componentCss);
© www.soinside.com 2019 - 2024. All rights reserved.