自定义 HTML 元素属性未显示 - Web 组件

Custom HTML element attribute not showing - Web-Components

我正在探索 Web 组件自定义 HTML 元素,但我 运行 遇到了向我的自定义元素添加自定义属性的问题:我在标记中设置的任何值都不会被接受。 对于像这样的简单元素,它应该显示 "flagtext" 属性中提供的文本,但它始终显示默认值。

<test-flag flagtext="my text"></test-flag> 

完整的 JSBin 示例是 here

JSBin 使用 Polymer 库(因为这是我唯一可以拉进去的东西)。我通常使用 webcomponents.js,结果相同。 Chrome 49 和 Firefox 45 中的结果相同。控制台或调试器中没有显示错误。

我在网上找到的每个示例都有类似的代码,但我尝试了各种版本,但它总是拒绝更新。我什至复制了一些示例到 JSBin 中,它们也不起作用。

有什么问题吗?我知道这是实验性技术,但它不起作用的一致性仍然令人惊讶。这个标准被放弃了吗? (我看到最新的 2016 年 4 月 W3C 自定义元素草案完全改变了它的方法。)

当我定义 "attributeChangedCallback" 函数时,它没有触发。 我可以通过 Javascript 轻松修改 属性,这不是问题。

但是为什么我不能像我应该的那样在标记中指定 属性?

编辑 - 完整代码

请注意,您需要将它们放入单独的文件中以便 HTML 导入,并且您需要 "webcomponents-lite.js" 库。

主要HTML文件

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style>
        test-flag
        {
            border: 1px solid blue;
        }
    </style>
</head>
<body>
  <script src="lib/webcomponents-lite.min.js"></script>
  <link rel="import" href="test-flag.html">

  Here is the custom test-flag component: 
  <p>      
  <test-flag flagtext="my text"></test-flag>  
</body>
</html>

文件:测试-flag.html

<template>

    <style>
    </style>

    Content:
    <div id="testflagID">
    </div>

</template>


<script>    

    (function() {

        var _currentScript = (document._currentScript || document.currentScript);
        var importDoc = _currentScript.ownerDocument;
        var customPrototype = Object.create(HTMLElement.prototype);        
        Object.defineProperty(customPrototype, 'flagtext', {value: '(default)', writable: true});       
        document.registerElement('test-flag', {prototype: customPrototype});


        customPrototype.createdCallback = function() 
        {
            var template = importDoc.querySelector('template');
            var clone = document.importNode(template.content, true);
            var idx = clone.querySelector("#testflagID");
            idx.textContent = this.flagtext;
            var root = this;
            var createdElement = root.appendChild(clone);

        };

    })();

</script>

有 2 个概念没有自动链接在一起。

在HTML代码中:

<test-flag flagtext="my text"></test-flag>

...术语 flagtext 是一个 HTML 属性 (不是 属性 ).

在JavaScript代码中:

Object.defineProperty(customPrototype, 'flagtext', {value: '(default)', writable: true})

...术语 flagtext 是 JavaScript 属性(不是 属性 ).

对于标准元素,浏览器会自动将 属性 值绑定到 属性 值(反之亦然)。对于自定义元素也是如此(使用标准 属性 )。但如果您想添加自定义 属性 ,则必须手动绑定它。

例如在createdCallback()方法中,添加:

this.flagtext = this.getAttribute( 'flagtext' ) || '(default)'

实时样本:

document.registerElement( 'test-flag' , {
  prototype: Object.create( HTMLElement.prototype, {
    flagtext: {
      value: '(default)',
      writable: true
    },
    createdCallback: {
      value: function() 
      {
        this.flagtext = this.getAttribute( 'flagtext' ) || this.flagtext
        this.innerHTML = 'flagtext=' + this.flagtext
      }
    },
  } )
} )
<test-flag flagtext='new content'>Hello</test-flag>

注意:attributeChangedCallback() 方法仅在 属性 被更改 之后 元素创建(这不是这里的情况)。