Вот скрипка, показывающая ошибку в консоли в Chrome 72 и Firefox 63:
https://jsfiddle.net/jr2z1ms3/1/
Код:
<script>
customElements.define('test-element', class extends HTMLElement {
constructor() {
super()
Promise.resolve().then(() => {
this.setAttribute('foo', 'bar')
})
}
})
</script>
<test-element>test</test-element>
В Chrome ошибка:
Uncaught DOMException: Failed to construct 'CustomElement': The result must not have attributes
В Firefox ошибка:
NotSupportedError: Operation is not supported
Если вы прокомментируете setAttribute
вызов, ошибка исчезает в обоих браузерах.
В следующем примере показано изменение атрибутов перед подключением элемента, что показывает, что это можно сделать с помощью макрозадач, но (несправедливо) не с помощью микрозадач:
( рабочая скрипка для фрагмента ниже)
customElements.define('test-element', class extends HTMLElement {
constructor() {
super()
setTimeout(() => {
this.setAttribute('foo', 'bar')
})
}
connectedCallback() {
console.log('foo attribute:', this.getAttribute('foo'))
}
})
const el = document.createElement('test-element')
console.log('no foo attribute:', el.getAttribute('foo'))
setTimeout(() => {
document.body.appendChild(el)
})
В первом примере я не устанавливаю атрибут в конструкторе, я откладываю на будущую микрозадачу.Так почему же браузеры жалуются?Если это предусмотрено спецификацией, то есть ли в спецификации «ошибка проектирования»?Почему мы не должны быть в состоянии это сделать?
на основе ответов ниже, я не понимаю, почему это ограничение требует , чтобы иметь место.Плохой разработчик все еще может создать беспорядок с или без этого ограничения движка браузера.
IMO, пусть разработчики решают (и документируют), как работают их пользовательские элементы.
Есть ли какие-то техническиеограничение, которое браузер иначе не может преодолеть, если бы мы были в состоянии установить атрибуты в конструкторе или микрозадаче после конструктора?