用户对vanilla JS webcomponent的风格

时间:2017-01-03 17:33:09

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

我有这个组件:

的index.html

<html>

<head>
    <title></title>
    <meta charset="UTF-8">
    <script src="clock.js"></script>
    <style>
        clock-digital div {
            background-color: green;
        }
    </style>
</head>

<body>
    <clock-digital></clock-digital>
</body>

</html>

clock.js

customElements.define('clock-digital', class extends HTMLElement {

    constructor() {
        super();
        var shadowRoot = this.attachShadow({
            mode: 'open'
        });
        this._clockID = setInterval(function () {
            var currentdate = new Date();
            var hours = ( (currentdate.getHours() < 10) ? '0' : '') + currentdate.getHours();
            var minutes = ( (currentdate.getMinutes() < 10) ? '0' : '') + currentdate.getMinutes();
            var seconds = ( (currentdate.getSeconds() < 10) ? '0' : '') + currentdate.getSeconds();
            shadowRoot.innerHTML = `
            <style>
                div {
                    display: inline-block;
                    width: 65px;
                    text-align: center;
                    background-color: whitesmoke;
                    font-style: italic;
                    border: 1px solid lightgray;
                    border-radius: 3px;
                    box-shadow: 2px 2px 3px;
                }
            </style>
            <div>
                ${hours}:${minutes}:${seconds}
            </div>`;
        }, 500);
    }

});

我希望组件的用户可以在时钟上定义他的风格。我尝试过:

<style>
        clock-digital div {
            background-color: green;
        }
    </style>

但它不起作用。我应该在影子根的某处使用插槽标签吗?实现这一目标的最佳做法是什么?

2 个答案:

答案 0 :(得分:2)

您可以在自定义元素中公开可以在外部设置的CSS properties

在您的示例中,您的元素可以定义--clock-background-color,用于设置div的背景颜色:

shadowRoot.innerHTML = 
  `<style>
     div {
       background-color: var(--clock-background-color, whitesmoke);
       /* ... */
     }
   </style>
   <div>
     ${hours}:${minutes}:${seconds}
   </div>`;

然后,您的元素的用户可以将背景颜色更改为绿色:

<style>
  clock-digital {
    --clock-background-color: green;
  }
</style>
<clock-digital></clock-digital>

codepen

请注意,Codepen演示程序使用Web Components polyfills用于非Chrome浏览器,但您可以将其注释掉,以确保它在Chrome中仍然可以使用。

答案 1 :(得分:2)

您还可以通过代表Shadow DOM根目录的:host 选择器(即自定义元素本身)获取用户定义的CSS规则的优先级。

在自定义元素中,使用:host设置内容样式:

shadowRoot.innerHTML = `
    <style>
        :host {
            display: inline-block;
            width: 65px;
            text-align: center;
            background-color: whitesmoke;
            font-style: italic;
            border: 1px solid lightgray;
            border-radius: 3px;
            box-shadow: 2px 2px 3px;
        }
    </style>
    <div>
        ${hours}:${minutes}:${seconds}
    </div>`

现在,用户可以使用标准CSS表示法定义自己的样式,就像任何HTML元素一样。这将覆盖:host规则定义的样式。

<style>
     clock-digital {
         background-color: green;
         color: white;
     }
</style>

customElements.define('clock-digital', class extends HTMLElement {
    constructor() {
        super();
        var shadowRoot = this.attachShadow({ mode: 'open' });
        this._clockID = setInterval(function () {
            var currentdate = new Date();
            var hours = ('0'+currentdate.getHours()).substr(-2,2)
            var minutes = ('0'+currentdate.getMinutes()).substr(-2,2)
            var seconds = ('0'+currentdate.getSeconds()).substr(-2,2) 
            shadowRoot.innerHTML = `
            <style>
                :host {
                    display: inline-block;
                    width: 65px;
                    text-align: center;
                    background-color: whitesmoke;
                    font-style: italic;
                    border: 1px solid lightgray;
                    border-radius: 3px;
                    box-shadow: 2px 2px 3px;
                }
            </style>           
            ${hours}:${minutes}:${seconds}`;
        }, 500);
    }
});
clock-digital  {
  background-color: green;
  color: white;
  font-weight: bold;
}
<clock-digital></clock-digital>