vanilla JavaScript中的Web组件

时间:2016-12-28 11:29:36

标签: web-component custom-element

我创建了一个没有任何框架的小型Web组件。这是我的index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <title></title>
    <meta charset="UTF-8">
    <script src="clock.js" async></script>
</head>

<body>
    <clock-digital></clock-digital>
    <script>
        console.log(document.querySelector('clock-digital').cID);
        document.querySelector('clock-digital').method();
    </script>
</body>

</html>

这是我的clock.js

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

    get cID() {}

    set cID(value) {}

    constructor() {
        super();
        var shadowRoot = this.attachShadow({
            mode: 'open'
        });
        var that = shadowRoot;
        this.cID = setInterval(function () {
            var currentdate = new Date();
            that.innerHTML = `<div style="display: inline; background-color: whitesmoke; font-style: italic;">${currentdate.getHours()}:${currentdate.getMinutes()}:${currentdate.getSeconds()}</div>`;
        }, 500);
    }

    method() {
        console.log('method');
    }

});

浏览器控制台显示以下错误:

undefined

(index):14 Uncaught TypeError: document.querySelector(...).method is not a function
at (index):14

为什么我的内联脚本无法访问cIDmethod()

2 个答案:

答案 0 :(得分:1)

您的内联脚本在导入 clock.js之前运行(由于您已添加到async标记的<script>属性,因此它是异步的。由于元素是在clock.js中定义的,因此当您的内联脚本尝试访问它们时,<clock-digital>.method<clock-digital>.cID尚不存在。

几个选项:

  • 删除async标记,以便在内联脚本运行之前同步导入(demo)。您将失去异步加载的优势,但这对您来说可能不是问题。
  • 超时后运行内联脚本(允许clock.js完成导入)

答案 1 :(得分:1)

要保持脚本异步(async),这有时会更好,您可以向onload元素添加<script>事件处理程序,它将调用您的内联脚本:

<script>
  function init() {
      console.log(document.querySelector('clock-digital').cID);
      document.querySelector('clock-digital').method();  
  }
</script>

<script src="clock.js" async onload="init()"></script>