В приведенном ниже фрагменте выдается ошибка, которая CustomElementParent
не определена, когда я пытаюсь расширить ее в CustomElementChild
.
Когда я снимаю флажок ! customElements.get('custom-element-parent')
, все работает.
В моем случае CustomElementParent
находится в стороннем скрипте, поэтому я не могу удалить оператор if.
Я думаю, это проблема условного определения класса. Есть ли способ расширить этот класс, если он определен условно?
<script>
if (! customElements.get('custom-element-parent')) {
class CustomElementParent extends HTMLElement {
constructor() {
super();
}
}
customElements.define('custom-element-parent', CustomElementParent);
}
if (! customElements.get('custom-element-child')) {
class CustomElementChild extends CustomElementParent {
constructor() {
super();
alert('test');
}
}
customElements.define('custom-element-child', CustomElementChild);
}
</script>
<custom-element-child></custom-element-child>
Объем. Классы имеют область действия, такую же, как и переменные.
if (true) {
let x = 5;
}
// you can’t access `x` here
(Мы не говорим о var
. Дело в том, что class
работает как объявления let
/const
/function в строгом режиме.)
Если вы не можете изменить область действия CustomElementParent
и не можете поместить свой код в ее область действия, вы не сможете получить к нему доступ таким образом. Вместо этого вы можете посмотреть его в реестре пользовательских элементов:
const CustomElementParent = customElements.get('custom-element-parent');
Полный пример:
{
class Hidden extends HTMLElement {
constructor() {
super();
console.info('parent');
}
}
customElements.define('custom-element-parent', Hidden);
}
const CustomElementParent = customElements.get('custom-element-parent');
class CustomElementChild extends CustomElementParent {
constructor() {
super();
console.info('child');
}
}
customElements.define('custom-element-child', CustomElementChild);
<custom-element-child></custom-element-child>
«Одним из вариантов может быть создание элемента этого типа, чтобы получить к нему доступ» — не усложняйте задачу. customElements.get('custom-element-parent')
подойдёт!
@Bergi: ошеломлен
Я никогда раньше не работал с пользовательскими элементами, я просто увидел это в вопросе и задался вопросом, что он делает :-)
Как и let
и const
, объявления class
имеют блочную область действия. Таким образом, областью действия объявления CustomElementParent
является блок if
, и он недоступен, когда вы доберетесь до второго блока if
.
Вы можете решить эту проблему, объявив имена вне области видимости, а затем назначив их с помощью выражений класса.
var CustomElementParent, CustomElementChild;
if (!customElements.get('custom-element-parent')) {
CustomElementParent = class CustomElementParent extends HTMLElement {
constructor() {
super();
}
}
customElements.define('custom-element-parent', CustomElementParent);
}
if (!customElements.get('custom-element-child')) {
CustomElementChild = class CustomElementChild extends CustomElementParent {
constructor() {
super();
alert('test');
}
}
customElements.define('custom-element-child', CustomElementChild);
}
<custom-element-child></custom-element-child>
Проблема в масштабах.
class
ограничено операторомif
, поэтомуCustomElementParent
выходит за рамки, когда вы доберетесь до определенияCustomElementChild
.