Saltar al contenido principal
Codigo Heroe
Tarea anterior
Manipulación del DOM7/21
A la lista de tareas
  1. 1. Buscar elementos para la lista de tareas
  2. 2. El evento change
  3. 3. Probar el evento change
  4. 4. Eliminar elementos con remove
  5. 5. Comprobar la longitud de una colección
  6. 6. Depurar el código
  7. 7. Colecciones estáticas y vivas
  8. 8. Mostrar un mensaje en la página
  9. 9. El evento submit
  10. 10. Cancelar el envío del formulario
  11. 11. Leer el texto de un campo con value
  12. 12. Plantillas y la etiqueta <template>
  13. 13. El contenido de <template> y DocumentFragment
  14. 14. Insertar y mover elementos con appendChild
  15. 15. Clonar elementos con cloneNode(false)
  16. 16. La clonación profunda con cloneNode(true)
  17. 17. Crear varias copias con un ciclo
  18. 18. Clonar la plantilla de una tarea
  19. 19. Completar e insertar una tarea nueva
  20. 20. Agregar un manejador a la tarea nueva
  21. 21. Ocultar el mensaje y vaciar el campo
Siguiente tarea
  • Matriz de skills
  • Cursos
  • Registro
  • Iniciar sesión

Loading…
En unos segundos, estará listo.

  • Teoría
  • Teoría

Colecciones estáticas y vivas

Encontramos el problema: la longitud de items no cambia al eliminar las tareas de la lista. ¿Por qué ocurre?

querySelectorAll encuentra los elementos una sola vez y devuelve una colección que conserva esos mismos nodos. Los cambios posteriores en el DOM no actualizan la composición de esa colección. Para obtener una lista nueva de coincidencias, tendríamos que hacer otra búsqueda.

Por eso esta colección se llama estática.

También existen colecciones vivas o dinámicas, que se actualizan con los cambios del DOM. Si se elimina del elemento padre uno de los elementos de la colección, también desaparece de ella. Una forma de obtener una colección viva es la propiedad children. Se consulta en el elemento padre y contiene todos sus elementos hijos directos. Esta es su sintaxis:

parentElement.children;

Comprobemos cómo funcionan las colecciones vivas. Sustituyamos la búsqueda con querySelectorAll por children y probemos el programa.

En la consola aparece NodeList junto a la colección. ¿Qué es?

Es el tipo de colección que devuelve querySelectorAll y que también se obtiene con otras API. Un NodeList puede contener nodos de distintos tipos, como elementos y nodos de texto (incluidos espacios y saltos de línea). La colección devuelta por querySelectorAll contiene los elementos que coinciden con el selector y es estática. Otros NodeList pueden ser vivos: depende de cómo se obtengan. Puedes leer más en la especificación y en MDN.

  • index.html
  • style.css
  • script.js
HTML
<!DOCTYPE html> <html lang="es"> <head> <meta charset="utf-8"> <title>Lista de tareas</title> <link href="style.css" rel="stylesheet"> </head> <body> <h1 class="visually-hidden">Lista de tareas</h1> <ul class="todo-list"> <li class="todo-list-item"> <label> <input class="todo-list-input" type="checkbox"> <span>Darle de comer al gato</span> </label> </li> <li class="todo-list-item"> <label> <input class="todo-list-input" type="checkbox"> <span>Irse del país</span> </label> </li> <li class="todo-list-item"> <label> <input class="todo-list-input" type="checkbox"> <span>Darse a la fuga</span> </label> </li> </ul> <p class="empty-tasks hidden">Todas las tareas completadas. No hay tareas nuevas.</p> <form class="add-form" action="https://codigoheroe.com/echo" method="post"> <input class="add-form-input" type="text" aria-label="Descripción de la tarea" placeholder="Por ejemplo, comprar un elefante" required> <button class="add-form-button" type="submit">Agregar tarea</button> </form> <template id="task-template"> <li class="todo-list-item"> <label> <input type="checkbox" class="todo-list-input"> <span></span> </label> </li> </template> <script src="script.js"></script> </body> </html>
CSS
@font-face { font-weight: 400; font-family: "Muller"; font-style: normal; font-display: swap; src: url("Muller.woff") format("woff"); } body { margin: 40px 32px; font-size: 18px; line-height: normal; font-family: "Muller", sans-serif; } .visually-hidden, .todo-list-input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; white-space: nowrap; border: 0; clip: rect(0 0 0 0); clip-path: inset(100%); } .hidden { display: none; } .todo-list { margin: 0; padding: 0; list-style: none; } .todo-list-item { margin-bottom: 12px; } .todo-list-item label { display: block; padding: 12px 18px; background-color: #ffffff; border-radius: 4px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); cursor: pointer; user-select: none; } .todo-list-item span { display: flex; align-items: center; } .todo-list-input + span::before { content: ""; display: inline-block; width: 16px; height: 16px; margin-right: 16px; background-color: #ffffff; border: 2px solid #69b253; border-radius: 4px; } .todo-list-input:checked + span::before { background-color: #69b253; background-image: url("check-white.svg"); background-repeat: no-repeat; background-position: center; } .todo-list-input:not(:checked):hover + span::before, .todo-list-input:not(:checked):focus + span::before { background-color: rgba(105, 178, 83, 0.2); } .empty-tasks { color: #69b253; } .empty-tasks::before { content: ""; width: 14px; height: 13px; margin-right: 13px; background-image: url("check-green.svg"); background-repeat: no-repeat; background-position: center; } .add-form { display: flex; } .add-form-input { flex-grow: 1; box-sizing: border-box; height: 46px; margin-right: 16px; padding: 12px; font: inherit; border: 1px solid #a1b5c4; border-radius: 4px; } .add-form-input:focus { border: 1px solid #69b253; outline: none; } .add-form-input:hover { box-shadow: 0 0 6px rgba(105, 178, 83, 0.6); } .add-form-input::placeholder { color: #a1b5c4; } .add-form-button { flex-shrink: 0; padding: 12px; font: inherit; color: #ffffff; background-color: #69b253; border: none; border-radius: 4px; user-select: none; touch-action: manipulation; } .add-form-button:hover, .add-form-button:focus { background-color: #5aa045; outline: none; } .add-form-button:active { background-color: #42862e; }
JavaScript
var list = document.querySelector('.todo-list'); var items = list.querySelectorAll('.todo-list-item'); var toggleEmptyListMessage = function () { console.log(items); if (items.length === 0) { console.log('¡Todos los objetivos completados!'); } }; var addCheckHandler = function (item) { var checkbox = item.querySelector('.todo-list-input'); checkbox.addEventListener('change', function () { item.remove(); toggleEmptyListMessage(); }); }; for (var i = 0; i < items.length; i++) { addCheckHandler(items[i]); }

El código ha cambiado, haz clic en "Actualizar" o activa la ejecución automática.

Ha ido a otra página

Haga clic dentro del mininavegador para poner el foco en esta ventana.

100%
Consola
ObjetivosRealizado
0
    1. En el valor de items, sustituye querySelectorAll('.todo-list-item') por children.
    2. Completa todas las tareas y revisa la consola. Prepárate para ver un poco de magia.
    Codigo Heroe

    © 2023-2026, codigoheroe.com