当使用用户嵌入的 JSON 字符串创建 HTML 自定义元素时(尽管字符串的类型与此处无关)...
<my-elem>
{ "some":"content" }
</my-elem>
我想
JSON.parse
它像这样...class MyElement extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({ mode:'open' });
this.root.appendChild(template.content.cloneNode(true));
}
connectedCallback() {
JSON.parse(this.innerHTML);
}
}
customElements.define('my-elem', MyElement);
const template = document.createElement('template');
template.innerHTML = `irrelevant`;
...并使用 Firefox v.63 获得完美的结果。
但是用 Chrome v.71 运行这个我得到
Uncaught SyntaxError: Unexpected end of JSON input
由于
this.innerHTML
返回一个空字符串。我还尝试了其他 DOM 方法来访问文本内容,但也都失败了。
现在我很无知,如何让它与 Chrome 一起工作。
顺便说一句:使用
<slot>
没有帮助,因为我不想呈现文本内容......只能访问它进行解析。已解决 :
最佳答案
为什么不让它更灵活并同时支持 src
属性和 data
属性(property)?
class MyElement extends HTMLElement {
static get observedAttributes() {
return ['src'];
}
constructor() {
super();
this.attachShadow({ mode:'open' });
this._data = {
name: '',
address: ''
};
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (oldVal !== newVal) {
const el = this;
fetch(newVal).then(resp => resp.json()).then(
data => {
el._data = data;
el.render();
}
);
}
}
render() {
this.shadowRoot.innerHTML = `
<div>
<div>${this._data.name}</div>
<div>${this._data.address}</div>
</div>`;
}
set address(val) {
this._data.address = val;
this.render();
}
set name(val) {
this._data.name = val;
this.render();
}
}
customElements.define('my-elem', MyElement);
setTimeout(() => {
let el = document.querySelector('my-elem');
el.name = 'The Joker';
el.address = 'Gothem';
setTimeout(() => {
el.setAttribute('src', 'data:application/json,%7B%22name%22:%22Thanos%22,%22address%22:%22Titan%22%7D')
}, 1500);
}, 1500);
<my-elem src="data:application/json,%7B%22name%22:%22Darth%20Vader%22,%22address%22:%22Death%20Star%22%7D"></my-elem>
使用 src 属性的优点是您可以传入 JSON,也可以传入将返回 JSON 的 URL。
这些属性允许您更改 DOM 中的单个值。
更改整个
innerHTML
可能不是正确的做法,但使用少量的 DOM 可能是正确的。您还可以更改 DOM 上的单个值或使用 LitHtml 之类的东西。
关于javascript - 如何访问 HTML 自定义元素中的内容文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53806938/