Quiero cambiar la propiedad de display de mi variable div objetivo de none a block .
const userListEl = document.getElementById('user-list').innerHTML; const template = Handlebars.compile(userListEl); const targetDiv = document.getElementById("userDetail"); fetch("https://5dc588200bbd050014fb8ae1.mockapi.io/assessment") .then(response => response.json()) .then((data) => { var userData = template({ usersList: data }) document.getElementById('test').innerHTML = userData; }).catch((error) => { console.log(error) }) this is my function const hanldeClick = () => { if (targetDiv.style.display === "none") { targetDiv.style.display = "block"; } else { targetDiv.style.display = "none"; } }; #userDetail { display: none; } <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <title>Exercise 1</title> </head> <body> <div id="test"></div> <script id="user-list" type="text/x-handlebars-template"> <ul class="people_list"> {{#each usersList}} <li> <p class="">{{name}}</p> <img src={{avatar}} alt={{name}}> <div id="userDetail"> <p>Id: {{id}}</p> <p>Created at: {{createdAt}}</p> </div> <button onclick="hanldeClick()"> Detail </button> </li> {{/each}} </ul> </script> <script type="text/javascript" src="app.js" defer></script> <script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script> </body> Quiero cambiar el valor de visualización none para block en un controlador onclick, pero cuando se hace clic en el botón aparece este error:
TypeError: no se pueden leer las propiedades de nulo (leyendo 'estilo')
¿Alguien me puede ayudar?
targetDiv es null cuando hace clic en el botón "Detalle" y activa la función handleClick porque no hay ningún elemento DOM con el id userDetail cuando invoca document.getElementById("userDetail"); .
Para verificar esto, puede registrar el valor de targetDiv inmediatamente después de su asignación:
const targetDiv = document.getElementById("userDetail"); console.log(targetDiv); // null ¿Por qué <div id="userDetail"> no es un elemento DOM?
Porque es parte de una plantilla dentro de una etiqueta de script . El atributo type="text/x-handlebars-template" que ha agregado a su bloque de script básicamente le dice al navegador que ignore lo que contiene. Esto es lo que le permite agregar contenido arbitrario, como los bigotes entendidos por la biblioteca Handlebars. Para obtener más información sobre esto: consulte Explicación de <script type = "text/template"> ... </script>
Para que su código haga referencia al elemento DOM con id userDetail , deberá obtenerlo del DOM después de haber inyectado su HTML renderizado en plantilla en el documento, es decir, después de configurar el #test innerHTML userData :
let targetDiv = null; fetch("https://5dc588200bbd050014fb8ae1.mockapi.io/assessment") .then(response => response.json()) .then((data) => { var userData = template({ usersList: data }) document.getElementById('test').innerHTML = userData; targetDiv = document.getElementById("userDetail"); }).catch((error) => { console.log(error) })He creado un violín para su referencia.
Además, incluso con esta solución, creo que encontrará que su código no funciona como esperaba. Parece que quiere que handleClick alterne un <div> hermano, y que este debería ser el efecto para cada <li> en su <ul> . Sin embargo, su document.getElementById("userDetail") devolverá solo el primer elemento con id userDetail , por lo que no importa en qué "Detalle" <button> se haga clic, solo se alternará el primer detalle de <li> . Deberá encontrar una manera de especificarle a su controlador qué detalle alternar.