javascript - 网页组件组合并不总是在 Chrome 中正确呈现
问题描述
我正在使用在 Firefox 和 safari 中正确呈现但在 chrome 中不正确呈现的 Web 组件组合。确实,有时嵌套组件没有显示在这个浏览器中,我不知道为什么以及如何解决这个问题。
这是代码:
index.html
从 json 文件中获取数据并相应地显示 2 个组件。
<html>
<head>
<meta charset="UTF-8">
<script type="module" src="/rect-shape.js"></script>
<script type="module" src="/shape-container.js"></script>
</head>
<body>
<p>rect-shape:</p>
<script>
const innerEl = document.createElement('rect-shape');
document.body.appendChild(innerEl);
fetch('./shapes.json')
.then(response => response.json())
.then(object => innerEl.color = object.shapes[0].color);
</script>
<hr>
<p>shape-container:</p>
<script>
const outerEl = document.createElement('shape-container');
document.body.appendChild(outerEl);
fetch('./shapes.json')
.then(response => response.json())
.then(object => outerEl.shapes = object.shapes);
</script>
</body>
</html>
shapes.json
:允许参数化来自外部服务的形状
{
"shapes": [
{
"color": "red"
},
{
"color": "blue"
}
]
}
shape-container.js
:
import '/rect-shape.js';
(function() {
const template = document.createElement('template');
template.innerHTML = `
<style>
rect-shape {
display: inline-table;
}
</style>
`;
class ShapeContainer extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
set shapes(data) {
try {
this.shapeArray = data;
this.renderShapes();
} catch (error) {
console.error(error);
}
}
renderShapes() {
this.shapeArray.forEach(shape => {
const innerElement = document.createElement('rect-shape');
this.shadowRoot.appendChild(innerElement);
innerElement.color = shape.color;
});
}
}
customElements.define('shape-container', ShapeContainer);
}());
rect-shape.js
:
(function() {
const template = document.createElement('template');
template.innerHTML = `
<style>
svg {
height: 100;
}
</style>
<div>
<svg id="port-view" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" />
</svg>
</div>
`;
class RectShape extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
set color(value) {
if (value) {
this.setAttribute("color", value);
} else {
this.removeAttribute("color");
}
}
get color() {
return this.getAttribute("color");
}
static get observedAttributes() {
return ["color"];
}
attributeChangedCallback(name) {
switch(name) {
case "color":
this.colorizeRect();
break;
}
}
colorizeRect() {
this.shadowRoot.querySelector('rect')
.style.setProperty('fill', this.color);
}
}
customElements.define('rect-shape', RectShape);
}());
我怎么解决这个问题?
谢谢,
解决方案
我清理了代码,保留了您的功能,Chrome 哪里出了问题?
class BaseElement extends HTMLElement {
constructor() {
super().attachShadow({mode: 'open'})
.append(document.getElementById(this.nodeName).content.cloneNode(true));
}
}
customElements.define('rect-shape', class extends BaseElement {
static get observedAttributes() {
return ["color"];
}
set color( value ) {
this.setAttribute("color", value);
}
attributeChangedCallback( name, oldValue, newValue ) {
if (name == "color") this.shadowRoot
.querySelector('rect')
.style
.setProperty('fill', newValue);
}
});
customElements.define('shape-container', class extends BaseElement {
set shapes( data ) {
data.forEach( shape => {
this.shadowRoot
.appendChild(document.createElement('rect-shape'))
.color = shape.color;
});
}
});
let shapeArray = {
"shapes": [{ "color": "red" }, { "color": "yellow" }, { "color": "blue" } ]
}
$Rect.color = 'rebeccapurple';
$Container.shapes = shapeArray.shapes;
<template id="RECT-SHAPE">
<style> svg { width: 70px }</style>
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" />
</svg>
</template>
<template id="SHAPE-CONTAINER">
<style> rect-shape { display: inline-table }</style>
</template>
rect-shape:
<br><rect-shape id=$Rect></rect-shape>
<br>shape-container:
<br><shape-container id=$Container></shape-container>
推荐阅读
- mysql - 某个属性的 SQL 更新,连接表
- python - 如何使用 Python 获取 Apple 产品的名称?
- .net - 如何使 .NET 5 上的 ASP.NET Core Web API 在 Azure 上运行?
- python - 使用 Parquet 存储具有嵌套结构的大型时间序列数据的最佳方法
- python - Python - 语音识别库导致 Discord 或 Zoom 的扬声器输出在 Windows 上被切断
- python - 使用 ipywidgets 在我的 jupyter notebook 中选择和上传文件时,为什么会得到 New napi_get_last_error_info?
- lua - 在保存错误时尝试使用“值”索引 nil
- python - if else 大学作业苦苦挣扎。Python
- c# - Startup 类的 Configure() 方法中服务的方法注入和构造函数注入有区别吗?
- python - 如果目录在 Python 中以数字结尾,则删除目录