导入 serval webcomponent 时,前一个自定义元素被下一个元素覆盖
previous custom element overwrited by next elements when import serval webcomponent
当一个页面中有多个自定义元素时,为什么总是显示最后一个元素而之前的元素被覆盖。例如:
第一部分:
<template id="cmpt-1">
webcomponent 1
</template>
<script type="text/javascript">
var thatDoc = document;
var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
var t = thisDoc.querySelector('#cmpt-1');
var protos = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var clone = thatDoc.importNode(t.content, true);
this.createShadowRoot().appendChild(clone);
}
}
});
thatDoc.registerElement('cmpt-1', {
prototype: protos
});
</script>
第二个组成部分:
<template id="cmpt-2">
webcomponent 2
</template>
<script type="text/javascript">
var thatDoc = document;
var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
var t = thisDoc.querySelector('#cmpt-2');
var protos = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var clone = thatDoc.importNode(t.content, true);
this.createShadowRoot().appendChild(clone);
}
}
});
thatDoc.registerElement('cmpt-2', {
prototype: protos
});
</script>
单页导入这两个组件时,如:
导入以上组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="import" href="cmpt1.html">
<link rel="import" href="cmpt2.html">
</head>
<body>
<cmpt-1></cmpt-1>
<cmpt-2></cmpt-2>
</body>
</html>
则只显示"component 2",第二个元素覆盖第一个元素。
在立即调用的函数表达式中将脚本标记中的代码包装起来以限制作用域可以解决您的问题。
<template id="cmpt-2">
webcomponent 2
</template>
<script type="text/javascript">
(function() {
var thatDoc = document;
var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
var t = thisDoc.querySelector('#cmpt-2');
var protos = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var clone = thatDoc.importNode(t.content, true);
this.createShadowRoot().appendChild(clone);
}
}
});
thatDoc.registerElement('cmpt-2', {
prototype: protos
});
})();
</script>
'cmpt-1'也一样。
您在全局范围内定义所有变量 - 两次,实际上 protos
是在呈现组件时指向第二个组件的指针。快速修复是将每个 protos
重命名为 cmpt1
和 cmpt2
之类的合理名称,并在 thatDoc.registerElement
中引用正确的变量。更好的解决方案是创建一个通用函数来初始化自定义组件并完全避免全局范围。
当一个页面中有多个自定义元素时,为什么总是显示最后一个元素而之前的元素被覆盖。例如:
第一部分:
<template id="cmpt-1">
webcomponent 1
</template>
<script type="text/javascript">
var thatDoc = document;
var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
var t = thisDoc.querySelector('#cmpt-1');
var protos = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var clone = thatDoc.importNode(t.content, true);
this.createShadowRoot().appendChild(clone);
}
}
});
thatDoc.registerElement('cmpt-1', {
prototype: protos
});
</script>
第二个组成部分:
<template id="cmpt-2">
webcomponent 2
</template>
<script type="text/javascript">
var thatDoc = document;
var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
var t = thisDoc.querySelector('#cmpt-2');
var protos = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var clone = thatDoc.importNode(t.content, true);
this.createShadowRoot().appendChild(clone);
}
}
});
thatDoc.registerElement('cmpt-2', {
prototype: protos
});
</script>
单页导入这两个组件时,如:
导入以上组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="import" href="cmpt1.html">
<link rel="import" href="cmpt2.html">
</head>
<body>
<cmpt-1></cmpt-1>
<cmpt-2></cmpt-2>
</body>
</html>
则只显示"component 2",第二个元素覆盖第一个元素。
在立即调用的函数表达式中将脚本标记中的代码包装起来以限制作用域可以解决您的问题。
<template id="cmpt-2">
webcomponent 2
</template>
<script type="text/javascript">
(function() {
var thatDoc = document;
var thisDoc = (thatDoc._currentScript || thatDoc.currentScript).ownerDocument;
var t = thisDoc.querySelector('#cmpt-2');
var protos = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var clone = thatDoc.importNode(t.content, true);
this.createShadowRoot().appendChild(clone);
}
}
});
thatDoc.registerElement('cmpt-2', {
prototype: protos
});
})();
</script>
'cmpt-1'也一样。
您在全局范围内定义所有变量 - 两次,实际上 protos
是在呈现组件时指向第二个组件的指针。快速修复是将每个 protos
重命名为 cmpt1
和 cmpt2
之类的合理名称,并在 thatDoc.registerElement
中引用正确的变量。更好的解决方案是创建一个通用函数来初始化自定义组件并完全避免全局范围。