嘿!
我很难理解HTML Imports的特定行为。我只是在导入中交换一行并获得完全不同的输出。
所以这就是我得到的......
的index.html
<!DOCTYPE html>
<html>
<head>
<link rel="import" href="./element-a.html">
<link rel="import" href="./element-b.html">
<link rel="import" href="./element-c.html">
</head>
<body>
<element-a></element-a>
</body>
</html>
元素-a.html
<template>
<element-b>
<element-c>Hi!</element-c>
</element-b>
</template>
<script>
console.log('registering a');
class ElementA extends HTMLElement {
constructor() {
super();
console.log('upgrading a');
const $template = this.constructor.ownerDocument.querySelector('template');
const $clone = $template.content.cloneNode(true);
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild($clone);
const $c = this.shadowRoot.querySelector('element-c');
const isDefined = () => console[$c.say ? 'debug' : 'error'](`say() is ${$c.say ? '': 'un'}defined`)
isDefined();
const undefined = this.shadowRoot.querySelectorAll(':not(:defined)');
const promises = [...undefined].map(el => customElements.whenDefined(el.localName));
console.log('undefined: ', undefined);
Promise.all(promises).then(() => {
console.log('ready');
isDefined();
});
}
}
ElementA.ownerDocument = document.currentScript.ownerDocument;
customElements.define('element-a', ElementA);
</script>
元素-b.html
<template>
<slot></slot>
</template>
<script>
console.log('registering b');
class ElementB extends HTMLElement {
constructor() {
super();
console.log('upgrading b');
const $template = this.constructor.ownerDocument.querySelector('template');
const $clone = $template.content.cloneNode(true);
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild($clone);
}
}
ElementB.ownerDocument = document.currentScript.ownerDocument;
customElements.define('element-b', ElementB);
</script>
元素-c.html
<template>
<slot></slot>
</template>
<script>
console.log('registering c');
class ElementC extends HTMLElement {
constructor() {
super();
console.log('upgrading c');
const $template = this.constructor.ownerDocument.querySelector('template');
const $clone = $template.content.cloneNode(true);
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild($clone);
}
say(words) {
console.log(words);
}
}
ElementC.ownerDocument = document.currentScript.ownerDocument;
customElements.define('element-c', ElementC);
</script>
我还创建了一个pen。现在令我困惑的是:如果我首先导入element-a
,我会得到此输出:
注册一个 升级 say()未定义
undefined:(2)[element-b,element-c]
注册b
升级b
注册c
升级c
准备
say()已定义
但如果我最后导入它,我会得到一个完全不同的输出和注册和升级的顺序。
注册b
注册c
注册 升级 升级b
升级c
说()是定义的 undefined:[]
准备
say()已定义
为什么?我有点期待最后的输出是总是发生的输出。它与插槽/ Shadow DOM有关吗?
答案 0 :(得分:1)
您应该在element-a.html中导入element-a的依赖项。 HTMLImport导入并注册组件,这就是为什么你得到一些未定义的原因,因为在导入其他文件之前注册组件(导入是异步的)。在注册组件之前,浏览器会在元素内部导入依赖项,直到所有依赖项都准备就绪。
的更多信息