最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Custom HTML element attribute not showing - Web-Components - Stack Overflow

programmeradmin2浏览0评论

I'm exploring web-ponents custom HTML elements, and I am running into a problem adding custom attributes to my custom elements: any value I set in the markup is never honored. For a simple element like this, which should show the text supplied in the "flagtext" attribute, it does always show the default value.

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

Full JSBin sample is here.

The JSBin uses the Polymer library (as this is the only thing I can pull in there). I am using webponents.js generally, same result. Both in Chrome 49 and in Firefox 45 gives same result. There is no error showing in the console or debugger.

Every sample I find on the web has similar code but I tried various versions and it always refuses to update. I even copied a few samples into JSBin and they do not work either.

What could be wrong? I understand it is experimental technology but the consistency with which this isn't working is still surprising. Has this standard been abandoned? (I see that the latest April 2016 W3C draft of custom elements has entirely changed its approach.)

When I define "attributeChangedCallback" function, it does not fire. I can easily modify the property via Javascript, this is not a problem.

But why can I not specify the property in markup, as I am supposed to?

Edit - full code

Note that you'll need to put these into separate files for the HTML import, and that you need the "webponents-lite.js" library.

Main HTML file

<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/webponents-lite.min.js"></script>
  <link rel="import" href="test-flag.html">

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

File: test-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>

I'm exploring web-ponents custom HTML elements, and I am running into a problem adding custom attributes to my custom elements: any value I set in the markup is never honored. For a simple element like this, which should show the text supplied in the "flagtext" attribute, it does always show the default value.

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

Full JSBin sample is here.

The JSBin uses the Polymer library (as this is the only thing I can pull in there). I am using webponents.js generally, same result. Both in Chrome 49 and in Firefox 45 gives same result. There is no error showing in the console or debugger.

Every sample I find on the web has similar code but I tried various versions and it always refuses to update. I even copied a few samples into JSBin and they do not work either.

What could be wrong? I understand it is experimental technology but the consistency with which this isn't working is still surprising. Has this standard been abandoned? (I see that the latest April 2016 W3C draft of custom elements has entirely changed its approach.)

When I define "attributeChangedCallback" function, it does not fire. I can easily modify the property via Javascript, this is not a problem.

But why can I not specify the property in markup, as I am supposed to?

Edit - full code

Note that you'll need to put these into separate files for the HTML import, and that you need the "webponents-lite.js" library.

Main HTML file

<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/webponents-lite.min.js"></script>
  <link rel="import" href="test-flag.html">

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

File: test-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>
Share Improve this question edited Jul 28, 2018 at 22:22 Supersharp 31.3k11 gold badges102 silver badges147 bronze badges asked May 16, 2016 at 11:36 nepdevnepdev 9772 gold badges12 silver badges20 bronze badges 3
  • 1 WebComponents are Chrome-only. It doesn't work in all browsers except Chrome and Opera (opera have the same engine than chrome). caniuse./#search=ponents . Avoid to use it – Marcos Pérez Gude Commented May 16, 2016 at 11:39
  • 1 (a)This isn't correct - the webponents.js polyfill enables the functionality in many browsers, and in my tests much of it works - but not this, (b) as mentioned above, the sample isn't working in Chrome either – nepdev Commented May 16, 2016 at 11:40
  • 1 enables the functionality is wrong. Emulates the behaviour, but that's not web ponents. However, I can't access jsbin. from my work, it's because is better that you share the code in the question itself (as the help center said). – Marcos Pérez Gude Commented May 16, 2016 at 11:43
Add a ment  | 

1 Answer 1

Reset to default 9

There are 2 concepts that are not automatically linked together.

In the HTML code:

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

...term flagtext is an HTML attribute (not a property).

In the JavaScript code:

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

...term flagtext is a JavaScript property (not an attribute).

For standard elements, the browser automatically binds the property value to the attribute value (and vice versa). For Custom Elements, too (with standard attributes). But if you want to add a custom attribute, you'll have to bind it manually.

For example, in the createdCallback() method, add:

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

Live sample:

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>

NB: the attributeChangedCallback() method is fired only when an attribute is changed after element creation (which is not the case here).

发布评论

评论列表(0)

  1. 暂无评论