Zer*_*Ten 10 javascript web-component
我在使用 createElement 创建 Web 组件时遇到问题。我收到此错误:
未捕获的 DOMException:无法构造“CustomElement”:结果在appendTodo 中不能有子级
class TodoCard extends HTMLElement {
constructor() {
super()
this.innerHTML = `
<li>
<div class="card">
<span class="card-content">${this.getAttribute('content')}</span>
<i class="fa fa-circle-o" aria-hidden="true"></i>
<i class="fa fa-star-o" aria-hidden="true"></i>
</div>
</li>
`
}
}
window.customElements.define('todo-card', TodoCard)
const todoList = document.getElementById('todo-list')
const todoForm = document.getElementById('todo-form')
const todoInput = document.getElementById('todo-input')
function appendTodo(content) {
const todo = document.createElement('todo-card')
todo.setAttribute('content', content)
todoList.appendChild(todo)
}
todoForm.addEventListener('submit', e => {
e.preventDefault()
appendTodo(todoInput.value)
todoInput.value = ''
})
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?谢谢。
Dan*_*man 14
constructor
永远无法创建在 中设置 DOM 内容的自定义元素document.createElement()
您将看到许多示例(包括我的示例),其中 DOM 内容是在构造函数中设置的。
这些元素永远无法创建document.createElement
当您使用:
<todo-card content=FOO></todo-card>
Run Code Online (Sandbox Code Playgroud)
元素(从 HTMLElement 扩展)具有所有 HTML 接口(它位于 HTML DOM 中),
并且您可以在构造函数中设置innerHTML
但是,当你这样做时:
document.createElement("todo-card");
Run Code Online (Sandbox Code Playgroud)
构造函数在没有 HTML 接口的情况下运行(该元素可能与 DOM 无关),
因此在构造函数中设置innerHTML会产生错误:
未捕获的 DOMException:无法构造“CustomElement”:结果不得有子级
来自https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance:
该元素不得获得任何属性或子元素,因为这违反了使用 createElement 或 createElementNS 方法的使用者的期望。一般来说,工作应该尽可能推迟到connectedCallback
使用shadowDOM时,您可以在构造函数中设置shadowDOM内容:
constructor(){
super().attachShadow({mode:"open"})
.innerHTML = `...`;
}
Run Code Online (Sandbox Code Playgroud)
connectedCallback: <todo-card content=FOO></todo-card>
Run Code Online (Sandbox Code Playgroud)
您还有另一个小问题:content 是默认属性,FireFox 不会停止警告您:

const todo = document.createElement("todo-card");
todo.setAttribute("content", "BAR");
document.body.appendChild(todo);
Run Code Online (Sandbox Code Playgroud)
可以写成:
const html = `<todo-card content="BAR"></todo-card`;
document.body.insertAdjacentHTML("beforeend" , html);
Run Code Online (Sandbox Code Playgroud)
connectedCallback运行多次!当您移动 DOM 节点时:
document.createElement("todo-card");
Run Code Online (Sandbox Code Playgroud)
"Learn Lit" 再次追加您的组件/应用程序必须如何处理这个问题取决于程序员
像 Lit、HyperHTML 和 Hybrids 这样的库实现了额外的回调来帮助完成这一切。
我建议先学习自定义元素 API,否则你学习的是工具而不是技术。
有了工具的傻瓜仍然是傻瓜
| 归档时间: |
|
| 查看次数: |
3761 次 |
| 最近记录: |