我已经使用customElements创建了Web组件。
<x-select>
<x-option>India</x-option>
<x-option>Africa</x-option>
</x-select>
执行顺序为:首先调用<x-select>
的构造函数,然后调用<x-option>
的构造函数。但是,我希望在<z-option>
之前先调用<z-select>
的构造函数。我该如何实现?
答案 0 :(得分:0)
有不同的实现方法。
通过JavaScript
1°创建<x-option>
:
xo1 = document.createElement( 'x-option' )
2°创建<x-select>
xs = document.createElement( 'x-select' )
3°附加<x-option>
xs.appendChild( xo1 )
通过HTML
在另一个自定义元素方法中而不是在其constructor()
中延迟父元素的初始化。然后在创建子元素之后调用此方法。
<x-select id="xs">
<x-option>India</x-option>
<x-option>Africa</x-option>
<script>xs.init()</script>
</x-select>
<script>
class XSelect extends HTMLElement {
constructor() {
super()
console.log('x-select created')
}
init() {
console.info('x-select init')
}
}
customElements.define('x-select', XSelect)
class XOption extends HTMLElement {
constructor() {
super()
console.log('x-option created')
}
}
customElements.define('x-option', XOption)
</script>
<x-select id="xs">
<x-option id="1">India</x-option>
<x-option id="2">Africa</x-option>
<script>xs.init()</script>
</x-select>
答案 1 :(得分:0)
Web组件的操作顺序有几个因素。
创建带有内部元素的组件时,将首先调用外部构造函数。然后调用内部构造函数。这很正常。
如果该组件不在真正的DOM树中,则不会发生其他任何事情。没有其他代码被调用。
将组件放入DOM之后,将调用connectedCallback
。从外部组件开始,然后从内部组件开始。
以下是不使用影子DOM的示例:
// Class for `<x-select>`
class XSelect extends HTMLElement {
constructor() {
super();
console.log('x-select constructor');
}
connectedCallback() {
console.log('x-select connectedCallback');
}
}
// Define our web component
customElements.define('x-select', XSelect);
// Class for `<x-option>`
class XOption extends HTMLElement {
constructor() {
super();
console.log('x-option constructor');
}
connectedCallback() {
console.log('x-option connectedCallback');
}
}
// Define our web component
customElements.define('x-option', XOption);
<x-select>
<x-option>India</x-option>
<x-option>Africa</x-option>
</x-select>
控制台输出为:
x-select constructor
x-select connectedCallback
x-option constructor
x-option connectedCallback
x-option constructor
x-option connectedCallback
即使在<x-select>
中使用影子DOM时,操作顺序也相同:
// Class for `<x-select>`
class XSelect extends HTMLElement {
constructor() {
super();
var sd = this.attachShadow({mode:'open'});
sd.innerHTML = '<slot></slot>';
console.log('x-select constructor');
}
connectedCallback() {
console.log('x-select connectedCallback');
}
}
// Define our web component
customElements.define('x-select', XSelect);
// Class for `<x-option>`
class XOption extends HTMLElement {
constructor() {
super();
console.log('x-option constructor');
}
connectedCallback() {
console.log('x-option connectedCallback');
}
}
// Define our web component
customElements.define('x-option', XOption);
<x-select>
<x-option>India</x-option>
<x-option>Africa</x-option>
</x-select>
如果我们使用JavaScript创建组件,则可以控制构造顺序。在下面的示例中,我以相同的顺序创建它们,但是您可以根据需要将其混合。
// Class for `<x-select>`
class XSelect extends HTMLElement {
constructor() {
super();
//var sd = this.attachShadow({mode:'open'});
//sd.innerHTML = '<slot></slot>';
console.log('x-select constructor');
}
connectedCallback() {
console.log('x-select connectedCallback');
}
}
// Define our web component
customElements.define('x-select', XSelect);
// Class for `<x-option>`
class XOption extends HTMLElement {
constructor() {
super();
console.log('x-option constructor');
}
connectedCallback() {
console.log(`x-option[${this.textContent}] connectedCallback`);
}
}
// Define our web component
customElements.define('x-option', XOption);
console.log('creating x-select');
var xs = document.createElement('x-select');
console.log('creating x-option 1');
var xo1 = document.createElement('x-option');
console.log('setting text of x-option 1');
xo1.textContent = 'India';
console.log('creating x-option 2');
var xo2 = document.createElement('x-option');
console.log('setting text of x-option 2');
xo2.textContent = 'Africa';
console.log('Adding x-option 1 to x-select');
xs.appendChild(xo1);
console.log('Adding x-option 2 to x-select');
xs.appendChild(xo2);
console.log('Adding x-select to container');
var c = document.getElementById('container');
c.appendChild(xs)
<div id="container"></div>
当我调用document.createElement
时,将调用构造函数,但是直到将元素放入DOM中,连接的回调函数才会触发。
以上代码的控制台输出为:
creating x-select
x-select constructor
creating x-option 1
x-option constructor
setting text of x-option 1
creating x-option 2
x-option constructor
setting text of x-option 2
Adding x-option 1 to x-select
Adding x-option 2 to x-select
Adding x-select to container
x-select connectedCallback
x-option[India] connectedCallback
x-option[Africa] connectedCallback
最后一个示例是创建DIV,然后将其innerHTML
设置为此:
<x-select>
<x-option>India</x-option>
<x-option>Africa</x-option>
</x-select>
// Class for `<x-select>`
class XSelect extends HTMLElement {
constructor() {
super();
//var sd = this.attachShadow({mode:'open'});
//sd.innerHTML = '<slot></slot>';
console.log('x-select constructor');
}
connectedCallback() {
console.log('x-select connectedCallback');
}
}
// Define our web component
customElements.define('x-select', XSelect);
// Class for `<x-option>`
class XOption extends HTMLElement {
constructor() {
super();
console.log('x-option constructor');
}
connectedCallback() {
console.log(`x-option[${this.textContent}] connectedCallback`);
}
}
// Define our web component
customElements.define('x-option', XOption);
console.log('creating div');
var d = document.createElement('div');
console.log('setting innerHTML of div');
d.innerHTML = `<x-select>
<x-option>India</x-option>
<x-option>Africa</x-option>
</x-select>`;
console.log('Adding div to container');
var c = document.getElementById('container');
c.appendChild(d)
<div id="container"></div>
这现在仅调用外部元素的构造函数,然后调用内部元素的构造函数。只有将<div>
放入DOM后,才调用对connectedCallback
的调用。再次,这些是首先需要外部元素,然后是内部元素。元素。