javascript - 使用 classList 从 JavaScript 在 Web 组件中动态添加类

标签 javascript web-component shadow-dom custom-element

如何给shadow DOM添加动态样式

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Document</title>
    <link rel="import" href="nav-component.html">
</head>
<body>
    <app-nav></app-nav>
</body>
</html>

导航组件.html

<template>
  <style>
    .btn {
        background-color: green;
        padding: 10px 20px;
    }
  </style>
    <button onclick="getstyles()">ENTER</button>
</template>
<script src="nav-component.js"></script>

导航组件.js

let template = document.currentScript.ownerDocument.querySelector('template');
let clone = document.importNode(template.content, true);
let proto = Object.create(HTMLElement.prototype);

proto.createdCallback = function () {
    let root = this.createShadowRoot();
    root.appendChild(clone);
}
document.registerElement('app-nav', {
    prototype: proto
});

function getstyles() {
    console.log('it works');
    document.querySelector('button').classList.add('btn');
    // document.currentScript.ownerDocument.querySelector('button').classList.add('btn');
}

必须在button元素中添加btn类,以便其样式添加到button元素

遇到错误 未捕获的类型错误:无法读取 null 的属性“classList”

Demo

最佳答案

首先,document.registerElement 已被弃用,所以我在这里回答了基于类的自定义元素解决方案...

解决方案是从document.currentScript.ownerDocument获取文档

class AppNavElement extends HTMLElement {
    constructor() {
        super()

        // import from ownerDocument
        const importDoc = document.currentScript.ownerDocument;
        let shadowRoot = this.attachShadow({mode: 'open'});
        const template = importDoc.querySelector('#template');
        const instance = template.content.cloneNode(true);
        shadowRoot.appendChild(instance);

        // Event Listener
        this.addEventListener('click', e => this.changeStyle());
    }

    changeStyle() {
        this.shadowRoot.querySelector('button').classList.add('btn')
    }
}

customElements.define('app-nav', AppNavElement)

更新:

要监听按钮元素只使用 connectedCallback 感谢@bhv

connectedCallback() { 
    let btn = this.shadowRoot.querySelector('button') 
    // Event Listener 
    btn.addEventListener('click', e => this.changeStyle()); 
}

关于javascript - 使用 classList 从 JavaScript 在 Web 组件中动态添加类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44258159/

相关文章:

javascript - javascript中的dispatchEvent所有元素

javascript - AngularJS Http 与 Jquery Ajax

javascript - Three.js 三.交互 三.transformControls

javascript - polymer 中的私有(private)非静态变量?

javascript - 如何在 Chrome 的文本区域中 "replace"选定的文本范围?

javascript - 内容安全策略。网络组件。 script src DataURI 。我可以通过 META 标记覆盖 HTTP HEADER 吗?

javascript - 让属性变得懒惰

javascript - 在自定义元素中迭代 HTMLCollection

javascript - 我如何判断一个元素是否在影子 DOM 中?

polymer - 是否可以使用 Polymer 查询包括 shadow dom 在内的所有元素?