- From: Joe Pea <notifications@github.com>
- Date: Wed, 02 Sep 2020 10:48:21 -0700
- To: w3c/webcomponents <webcomponents@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/webcomponents/issues/418/685896020@github.com>
Timing issues are still a problem. This works well:
```html
<my-el id="el"></my-el>
<script>
const defined = el.matches(':defined')
// This code needs to do something once the element is defined.
if (defined) {
console.log('el is defined')
} else {
console.log('el not yet defined')
customElements.whenDefined(el.tagName.toLowerCase()).then(() => {
console.log('el is defined? ', el.matches(':defined')) // true (good)
})
}
</script>
<!-- Definition happens sometime later: -->
<script>
customElements.define('my-el', class extends HTMLElement {
constructor() {
super()
console.log('my-el constructor')
}
connectedCallback() {
console.log('my-el connected')
}
})
</script>
```
[codepen example](https://codepen.io/trusktr/pen/de05b6bc70b2ae3352fbc398d4e3b444)
But this does not work:
```html
<script>
const el = document.createElement('my-el')
const defined = el.matches(':defined')
// This code needs to do something once the element is defined (upgraded).
if (defined) {
console.log('el is defined')
} else {
console.log('el not yet defined')
customElements.whenDefined(el.tagName.toLowerCase()).then(() => {
console.log('el is defined? ', el.matches(':defined')) // false (bad)
})
}
</script>
<!-- Definition happens sometime later: -->
<script>
customElements.define('my-el', class extends HTMLElement {
constructor() {
super()
console.log('my-el constructor')
}
connectedCallback() {
console.log('my-el connected')
}
})
</script>
<!-- The element is appended sometime later: -->
<script>
document.body.append(el)
</script>
```
[codepen example](https://codepen.io/trusktr/pen/2fbf39c2913714546f1522cbbc5e2c06)
I think there should be a better solution to this. Some possible solutions:
1. Upgrade the element reference even if it is not in the DOM. In the second example, the `customElements.define` call would run the constructor, and `:defined` would be true before the `whenDefined.then` callback runs. This would greatly improve intuitiveness of code that wishes to rely on `whenDefined`
The current output of the second example is
```
el not yet defined
el is defined? false
my-el constructor
my-el connected
```
but the new output would be
```
el not yet defined
my-el constructor
el is defined? true
my-el connected
```
2. Provide a new builtin API to allow waiting for an element to be upgraded. f.e. `el.addEventListener('defined', () => {...})` . This does not improve the intuitiveness of `whenDefined` code, but provides a workaround in a non-breaking way as this would not change behavior of existing code in the wild. (I still prefer the first option).
(cc @justinfagnani as you've discussed these sorts of issues in other topics too)
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/418#issuecomment-685896020
Received on Wednesday, 2 September 2020 17:48:34 UTC