Отложенный вызов setAttribute в конструкторе Custom Element вызывает ошибку DOM. Это ошибка?

Ответ из официальной документации :

Условное наследование

Поскольку имя шаблона для родителя может быть любым допустимым выражением Twig, это возможно сделать механизм наследования условным:

{% extends standalone ? "minimum.html" : "base.html" %}

В этом примере шаблон расширит шаблон макета «minimum.html», если отдельная переменная будет равна true, а в противном случае - «base.html».

blockquote>

1
задан trusktr 26 February 2019 в 18:55
поделиться

2 ответа

Согласно спецификации есть определенные вещи, которые вы никогда не должны делать в конструкторе:

При создании пользовательских конструкторов элементов авторы связаны следующими требованиями соответствия: [ 1115]

  • Безпараметрический вызов super () должен быть первым оператором в теле конструктора, чтобы установить правильную цепочку прототипов и это значение, прежде чем будет запущен какой-либо дополнительный код.

    [ 117]
  • Оператор return не должен появляться где-либо внутри тела конструктора, если только он не является простым ранним возвратом (возврат или возврат этого).

  • Конструктор не должен использовать методы document.write () или document.open ().

  • Атрибуты и дочерние элементы не должны проверяться , так как в случае отсутствия обновления ни один не будет присутствовать, а использование обновлений делает элемент менее пригодным для использования.

  • Элемент не должен иметь никаких атрибутов или дочерних элементов , поскольку это нарушает ожидания потребителей, которые используют методы createElement или createElementNS.

  • В общем, работа должна быть максимально отложена до connectedCallback - особенно работа, включающая выборку ресурсов или рендеринг. Однако обратите внимание, что connectedCallback можно вызывать более одного раза, поэтому любая работа по инициализации, которая действительно является одноразовой, будет нуждаться в защите, чтобы предотвратить ее выполнение дважды.

  • В общем случае конструктор следует использовать для установки начального состояния и значений по умолчанию, а также для настройки прослушивателей событий и, возможно, теневого корня.

Некоторые из этих требований проверяются во время создания элемента, прямо или косвенно, и их несоблюдение приведет к созданию пользовательского элемента, который не может быть реализован синтаксическим анализатором или API DOM.

Проблема с вашим примером заключается в том, что Promise решается немедленно и, таким образом, все еще находится в конструкторе.

Если вы измените свой код на это:

customElements.define('test-element', class extends HTMLElement {
  constructor() {
    super()
    setTimeout(() => {
        this.setAttribute('foo', 'bar')
    }, 100)
  }
})
<test-element>test</test-element>

Тогда это работает, потому что setTimeout получает Вы вышли из конструктора.

0
ответ дан Intervalia 26 February 2019 в 18:55
поделиться

В спецификации это упоминается:

Это верно даже в том случае, если работа выполняется внутри инициируемой конструктором микрозадачи, поскольку контрольная точка для микрозадачи может возникнуть сразу после построения. [ 112]

0
ответ дан abraham 26 February 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: