Quiero seleccionar el ícono con id='home-i' y darle un efecto de clic; sin embargo, cuando uso document.querySelector('left-navbar nav'); devuelve como null . Estoy usando un elemento personalizado básico de javascript, que parece estar causando el problema.
Intenté usar shadowRoot y usar un truco setTimeout como se muestra en esta publicación . Ambos métodos no parecían funcionar.
<left-navbar></left-navbar> es el elemento personalizado.
<body> <main> <!-- Heading --> <h1 id='reading-heading'>Chapter 1</h1> <!-- Navigation Bar --> <left-navbar></left-navbar>Componente personalizado
class Navbar extends HTMLElement { connectedCallback() { setTimeout(() => { this.innerHTML = ` <nav id='navbar'> <i class="fas fa-home" id='home-i'></i> <hr class="line"> <i class="fas fa-arrow-alt-circle-left" id='back-i'></i> <i class="fas fa-brain"></i> <i class="fas fa-lightbulb" id='quiz-i'></i> <i class="fas fa-sign-out-alt" id='exit-i'></i> </nav> ` }); } } customElements.define('left-navbar', Navbar)Javascript usando el selector de consultas
const homeBtn = document.querySelector('left-navbar nav'); homeBtn.addEventListener('click', () => { window.location.href = 'index.html'; changePageTitle(0); })Que setTimeout hace que su función se ejecute después de que se borre EventLoop,
así que después de que se analice todo el otro código JS.
Vea el código a continuación, se muestra other code en la consola y luego se muestra setTimeout .
Por lo tanto, cuando intentó agregar un controlador de clic, aún no había HTML para usar querySelector .
Si el controlador de clics está vinculado al componente web, agregue el controlador de clics dentro del componente web.
<script> customElements.define("my-element", class extends HTMLElement { connectedCallback() { setTimeout(() => console.log("setTimeout")); this.innerHTML = `<nav>Element Nav InnerHTML</nav>`; this.querySelector("nav").onclick = (evt) => alert("clicked!"); } }); console.log("other code"); // your addEventListener was here </script> <my-element></my-element>Notas:
Como se menciona en los comentarios, se requiere setTimeout cuando desea LEER el HTML interno del componente innerHTML en la devolución de llamada connectedCallback ; porque connectedCallback se activa en la etiqueta de apertura , por lo que su HTML interno aún no se analiza. setTimeout ejecuta después de analizar todo el DOM y JS (en línea).
Inmersión profunda en esta publicación SO
Aquí uso un detector de eventos onclick en línea ; addEventListener es para casos de uso en los que (podría) querer agregar múltiples oyentes en un elemento DOM.
Ver: addEventListener vs onclick
También puede hacer: this.onclick = (evt) => alert("clicked!");