在创建带有用户嵌入的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>
没有帮助,因为我不想呈现文本内容...仅访问它进行解析。
已解决:
答案 0 :(得分:0)
您应该等待内容出现。
在大多数情况下,只需延迟一下即可解决问题:
connectedCallback() {
setTimeout( () => JSON.parse(this.innerHTML) )
}
或者,实际上<slot>
可以帮助解决slotchange
事件。您可以隐藏渲染或删除不想要的内容。
答案 1 :(得分:0)
为什么不使其更加灵活并同时支持src
属性和data
属性?
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的方法。