如何等待“自定义元素”引用被“升级”? [英] How to wait for Custom Element reference to be "upgraded"?

查看:84
本文介绍了如何等待“自定义元素”引用被“升级”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我引用了一个元素,该元素有时会升级为自定义元素。我如何等待它升级?

I have a reference to an element that will at some point be upgraded to a custom element. How do I wait for it to be upgraded?

例如,假设 el 是参考。如果假设为此目的附加了诺言,则代码可能类似于

For example, suppose el is the reference. If it hypothetically had a promise attached to it for this purpose, code could be similar to

await el.upgradePromise
// do something after it has been upgraded.

那当然不存在,但是描述了我想做什么。也许没有轮询就没有办法吗?如果使用轮询,我将轮询什么(假设我没有对应该升级到的类构造函数的引用)。也许我可以轮询 el.constructor 并等待它不是 HTMLElement ,或者等待它不成为 HTMLUnknownElement

That of course doesn't exist, but describes what I want to do. Maybe there is no way to do it without polling? If I use polling, what would I poll for (suppose I don't have a reference to the class constructor that it should upgrade to). Maybe I can poll el.constructor and wait for it not to be HTMLElement, or wait for it not to be HTMLUnknownElement?

编辑:对于背景,我有一些类似以下的代码,其中使用setTimeout依次是使代码正常工作。第一个 console.log 输出false,而超时中的则输出true。

for background, I have some code like the following, where using setTimeout is a hack in order for the code to work. The first console.log outputs false, while the one in the timeout outputs true.

import OtherElement from './OtherElement'

class SomeElement extends HTMLElement {
    attachedCallback() {
        console.log(this.children[0] instanceof OtherElement) // false

        setTimeout(() => {
            console.log(this.children[0] instanceof OtherElement) // true
        }, 0)
    }
}

其中 OtherElement 是对Custom Element类的引用,该类将在某个时候注册。请注意,我使用的是Chrome v0 document.registerElement 。需要超时是因为如果首先按以下代码注册 SomeElement ,则 OtherElement 尚未注册,因此,因此,如果 SomeElement 元素的子元素应该是 OtherElement 的实例,则该元素不会是

where OtherElement is a reference to a Custom Element class that will at some point be registered. Note, I'm using Chrome v0 document.registerElement in my case. The timeout is needed because if SomeElement is registered first as in the following code, then OtherElement will not yet be registered, so therefore if the child of the SomeElement element is expected to be an instance of OtherElement, then that will not be the case until those elements are upgraded next.

document.registerElement('some-el', SomeElement)
document.registerElement('other-el', OtherElement)

理想情况下,这样的超时是不可取的,因为如果升级恰好花费更长的时间(由于某些未知原因,可能取决于浏览器的实现),所以超时破解也将失败。

Ideally, a timeout like that is undesirable, because if upgrade happens to take a longer time (for some unknown reason that could depend on the browser implementation) then the timeout hack will also fail.

我想要一种绝对的方法等待升级,而不会发生故障,并且如果可能,也不会进行轮询。

I'd like an absolute way to wait for something to be upgraded without possible failure, and without polling if possible. Maybe it needs to be canceled after some time too?

编辑:理想的解决方案将使我们能够等待任何第三方自定义元素的升级而无需修改

The ideal solution would allow us to wait for the upgrade of any third-party custom elements without needing to modify those elements before runtime, and without having to monkey patch then at runtime.

编辑:通过观察Chrome的v0行为,似乎是第一次调用 document.registerElement('some-el',SomeElement)导致这些元素被升级并在之前触发其 attachedCallback 方法 OtherElement 的注册,因此子代将不是正确的类型。然后,通过延迟逻辑,在子项也升级为 OtherElement 类型之后,我可以运行逻辑。

From observing Chrome's v0 behavior, it seems like the first call to document.registerElement('some-el', SomeElement) causes those elements to be upgraded and their attachedCallback methods to be fired before the registration of OtherElement, so the children will not be of the correct type. Then, by deferring logic, I can run logic after the children have also been upgraded to be of type OtherElement.

编辑:这是显示问题的jsfiddle ,这是显示超时入侵解决方案。两者都是使用Chrome Canary中的Custom Elements v1 API编写的,在其他浏览器中均无法使用,但是使用带有$code> document.registerElement 和 attachedCallback ,而不是 customElements.define connectedCallback 。 (请参见两个小提琴中的控制台输出。)

Here's a jsfiddle that shows the problem, and here's a jsfiddle that shows the timeout hack solution. Both are written with Custom Elements v1 API in Chrome Canary, and won't work in other browsers, but the problem is the same using Chrome Stable's Custom Elements v0 API with document.registerElement and attachedCallback instead of customElements.define and connectedCallback. (See console output in both fiddles.)

推荐答案

您可以使用 window.customElements.whenDefined( my-element),它返回一个 Promise ,可用于确定何时升级某个元素。

You can use window.customElements.whenDefined("my-element") which returns a Promise that you can use to determine when an element has been upgraded.

window.customElements.whenDefined('my-element').then(() => {
  // do something after element is upgraded
})

这篇关于如何等待“自定义元素”引用被“升级”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆