Construí mi componente web DataUint y le asigné una etiqueta <data-uint> como esta:
class DataUint extends HTMLElement { ... set value(x) { ... } ... } customElements.define("data-uint", DataUint);Al crear y acceder a un componente como este:
x = document.createElement('data-uint'); x.value = 10; la llamada al value de hecho llama al método setter y realiza su función.
Sin embargo, cuando incorporé mi componente en el código html:
<body> <data-uint id='num'></data-uint> </body>y tratando de acceder/usarlo así:
x = body.children[0]; x.value = 10; la llamada a value establece una nueva propiedad en Element a la que x hace referencia, pero nunca llama al método setter del componente web. Sin embargo, la x se refiere al elemento correcto en la página (mi componente) que verifiqué llamando a otros métodos de elemento estándar. Parece que este método de acceso devuelve un Element genérico que ignora las especializaciones.
Pregunta:
Supongo que me falta algún concepto básico aquí. ¿Cómo accedo al componente definido en html desde JavaScript de una manera que me permita usar sus funciones miembro?
Probablemente estés ejecutando x = body.children[0]; x.value = 10; antes de que se defina el componente. También tenga en cuenta que, a menos que haya declarado un body de variable local antes de que se ejecute el código, el body no estará undefined y probablemente quiera usar const x = document.body.children[0]; .
Agregue esta línea de código:
const x = document.body.children[0]; console.log(x.constructor.name); x.value = 10; Si eso le da HTMLElement , su componente no está definido en ese momento. Si aún no está definido, no hay setter para ejecutar.
Para verificar, también puede hacer console.log(x.matches(':defined')); .
Para solucionarlo, envuelva su código en un oyente DOMContentLoaded o espere a que se defina el componente:
customElements .whenDefined('data-uint') .then((promise) => { const x = document.body.children[0]; console.log(x.constructor.name); x.value = 10; });