javascript - 如何等待自定义元素引用为 "upgraded"?

标签 javascript dom polymer web-component custom-element

我有一个元素的引用,该元素将在某个时候升级为自定义元素。如何等待升级?

例如,假设el 是引用。如果假设它为此目的附加了一个 promise ,代码可能类似于

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

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

编辑:对于背景,我有一些类似下面的代码,其中使用 setTimeout 是为了让代码正常工作。第一个 console.log 输出 false,而超时中的那个输出 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 是对将在某个时候注册的自定义元素类的引用。请注意,在我的案例中,我使用的是 Chrome v0 document.registerElement。超时是必需的,因为如果 SomeElement 像下面的代码一样首先注册,那么 OtherElement 将不会被注册,因此如果 SomeElement 元素应该是 OtherElement 的一个实例,然后在接下来升级这些元素之前不会是这种情况。

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

理想情况下,这样的超时是不可取的,因为如果升级碰巧需要更长的时间(由于某些未知原因,可能取决于浏览器的实现),那么超时 hack 也会失败。

我想要一种绝对的方式来等待某些东西升级而不会出现故障,并且尽可能不进行轮询。也许一段时间后也需要取消?

编辑:理想的解决方案允许我们等待任何第三方自定义元素的升级,而无需在运行前修改这些元素,也无需在运行时进行猴子补丁。

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

编辑:这是一个显示 the problem 的 jsfiddle ,这是一个显示 the timeout hack solution 的 jsfiddle .两者都是用 Chrome Canary 中的 Custom Elements v1 API 编写的,在其他浏览器中不起作用,但是使用 Chrome Stable 的 Custom Elements v0 API 和 document.registerElementattachedCallback 的问题是一样的 而不是 customElements.defineconnectedCallback。 (请参阅两个 fiddle 中的控制台输出。)

最佳答案

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

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

关于javascript - 如何等待自定义元素引用为 "upgraded"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39196503/

相关文章:

javascript - 从日期对象获取浏览器的时区和日期

polymer - 是否可以在Polymer中跨Web组件(和导入)共享mixin?

javascript - 是否可以阻止 jQuery.find() 在 DOM 树的某些节点下面进行搜索?

javascript - WTForms-Javascript : pass onclick to WTF field

javascript - 如何将链接值从 "Choose"更改为 "Chosen"?

javascript - 处理结束后全局变量是否存储在浏览器中?

javascript - 如何获取 Chrome/WebKit 中过渡元素的当前颜色?

javascript - 没有引用 DOM 对象

html - 使两个 div 向右浮动并重叠?

polymer - 如何在 Polymer2 中使用带有数据绑定(bind)的插槽注入(inject)模板