Это не работает:
<!-- wtf.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title></title>
<script type="module" src="./wtf.js"></script>
</head>
<body>
<script>
const myElement = document.createElement('my-element')
document.body.appendChild(myElement)
myElement.callMe()
</script>
</body>
</html>
// wtf.js
customElements.define('my-element', class extends HTMLElement {
constructor() {
super()
}
callMe() {
window.alert('I am called!')
}
})
Firefox бросает мне неприятное исключение в строке myElement.callMe()
. Видимо, "myElement.callMe is not a function
" .
Я запутался, почему это так? Насколько я понимаю, как только я набираю const myElement = document.createElement('my-element')
, я получаю объект, тип которого не является общим HTMLElement
, а объект моего класса, который я написал, который расширяет HTMLElement
! И этот класс выставляет callMe
.
Я подтвердил, что мое использование модулей, похоже, является виновником здесь. Этот код работает как положено:
<!-- wtf.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title></title>
</head>
<body>
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
super()
}
callMe() {
window.alert('I am called!')
}
})
const myElement = document.createElement('my-element')
document.body.appendChild(myElement)
myElement.callMe()
</script>
</body>
</html>
Да, я знаю, что вещи, определенные в модуле, относятся к этому модулю. Но здесь это даже не кажется (для меня) проблемой вопроса. Например, если я сделаю внутри модуля что-то вроде этого:
function callMe() {/*blah blah */}
window.callMe = callMe
тогда я смогу использовать callMe
вне модуля в любом случае, потому что модуль предоставил эту функцию другими способами, чем export
(на этот раз путем назначения ее глобальной window
объект).
То же самое, насколько я понимаю, должно происходить в моем случае использования. Несмотря на то, что я определяю callMe
в классе, ограниченном модулем, этот метод класса должен быть доступен вне модуля, поскольку он является свойством объекта этого класса, который открывается путем вызова document.createElement('my-element')
. Но, очевидно, этого не происходит.
Это действительно странно для меня. Похоже, что модуль принудительно устанавливает свою область видимости путем запутывания с типами, не относящимися к функциям, возвращающими (!!) - так что в этом случае это так же, как если бы модуль магически вызывал document.createElement
для приведения объекта он возвращается в иерархию наследования (до HTMLElement
)?!?! Это поразительно для меня.
Может кто-нибудь, пожалуйста, очистить мою путаницу?
(И если я определяю пользовательский элемент внутри модуля, как я могу предоставить его API за пределами этого модуля?)