Custom Elements in Templates

#!/JoePea joe at trusktr.io
Sat Nov 16 18:04:50 UTC 2019


This is indeed an ugly problem that I've faced when making Custom
Elements. The problem is: in templates, custom elements do not get
"upgraded" into their identity. They only get "upgraded" once they are
inserted into the live DOM.

The best you can do is make deferred code in your custom element
constructor to check for existing property values before overriding
them with getters/setters, and make sure to store the already-existing
values.

It would also help for your elements to emit a "ready" event, or
similar, once the constructor has fired, and consumer code can listen
for this event (on a parent element where it has bubbled to) to
finally begin using any of the custom element's APIs.

Yes, this is very ugly. I really dislike this about custom elements.
But once you learn how to abstract it, then you'll be beyond the
problem. Libraries like Polymer, SkateJS, etc, abstract this stuff
away, so that if you stick with their recommended APIs, you don't hit
the issue.

But yeah, discourse.wicg.io is a good place to ask. Another good place
to ask, where all vendors talk about the spec, is
github.com/w3c/webcomponents/issues.

All the best,
- Joe


On Tue, Sep 24, 2019 at 9:39 AM Isiah Meadows <isiahmeadows at gmail.com> wrote:
>
> You'd have better luck in https://discourse.wicg.io than here. This is about the ECMAScript spec and JavaScript the language, not anything related to the web platform at large.
>
> On Tue, Sep 24, 2019 at 09:55 Randy Buchholz <work at randybuchholz.com> wrote:
>>
>> I’m putting a custom element in a template and then “selecting” it out to Window level. It seem to loose its identity as a custom element.
>>
>>
>>
>> ```
>>
>> // In page
>>
>> <template id="holder">
>>
>>     <my-element field="A"></my-element>
>>
>> </template>
>>
>>
>>
>> <script type="module">
>>
>>     class MyElement extends HTMLElement {
>>
>>         constructor() {
>>
>>             super();
>>
>>         }
>>
>>         get Field() { return this.getAttribute("field");}
>>
>>     }
>>
>>
>>
>>     window.customElements.define("my-element", MyElement);
>>
>> </script>
>>
>>
>>
>> <script>
>>
>>     const frag = document.querySelector("#holder").content;
>>
>>     const el = frag.querySelector("my-element");
>>
>>     console.log({el});
>>
>> </script>
>>
>> ```
>>
>>
>>
>> When `<my-element>` is a page level and not in a template I can read `xxx.Field`. When it comes from within a template it seems to no longer act like the custom element – xxx.Field isn’t defined. The script selecting it is at “Window” level, so shouldn’t it “cast” correctly?
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>
> --
> -----
>
> Isiah Meadows
> contact at isiahmeadows.com
> www.isiahmeadows.com
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss


More information about the es-discuss mailing list