No entiendo la propiedad content funcionando con el método cloneNode()

Avatar

@germanbaena67846

Estimada comunidad, hago el ejercicio correspondiente de esta clase y funciona de igual manera usando el método cloneNode() o sin usarlo.

Si la propiedad 'content' devuelve el contenido de la plantilla de un elemento <template> y este queda almacenado en la constante myNewTemplate, ¿para qué necesitamos cloneNode()?

La única diferencia que veo es que cuando utilizo cloneNode(), en Elements de las Developer Tools, muestra el html del <template>, sin cloneNode() no lo muestra, y debe ser obvio pues se usa cloneNode(true); pero de igual manera el ejercicio funciona con cloneNode() o sin cloneNode()

Necesito entender por qué se usa content.cloneNode() y no solamente content si el ejercicio funciona igual de las dos maneras.

Gracias por su valiosa colaboración.

Dejo las imágenes respectivas:

Avatar

@angelsalvador

Piensalo de la siguiente manera:

Un template tiene la idea de poder reutilizarse, por lo tanto si lo usas directamente con template.content y modificas la estructura interna que tiene, solo lo podrás hacerlo una vez. Compruébalo Intentando crear otra variable que almacene template.content y trata de modificar el h2 y el p de la misma forma que hiciste con el primero. Te darás cuenta que te arrojará un null, ya que la estructura interna que tenia el template la modificaste en el primero.

Entonces, como dato importante, el contenido que tiene document fragment, es almacenado en memoria, mas no en el mismo DOM y esto ayuda para el rendimiento de la aplicación/web al momento de clonarlo y reutilizarlo. Como dije al principio, la idea de un template es poder reutilizarlo.

Avatar

@germanbaena67846

Angel, gracias por interesarse en resolverme esta duda; según entendí si no uso cloneMode() no puedo reutilizar el document fragment, sin embargo, aún así no entiendo bien como hacer las modificaciones pertinentes para obtener null y darme cuenta bien del problema. Por favor, si tienes algún tiempo disponible, quedaría muy agradecido si a través de un ejemplo con código como tu dices, me permites observar al problema. Aprender es un proceso, unos van más rápido que otros! Nuevamente Gracias.

Avatar

@angelsalvador

Claro, te lo explico mejor con un ejemplo:

const template = document.getElementById('template');

       //Aqui estas creando una variable para obtener el contenido del template
       const newTemplate = template.content;

       // Aqui estas modificando directamente.
       newTemplate.querySelector('h2').textContent = 'EDTeam';
       newTemplate.querySelector('p').textContent = 'futuro';

       // Aqui lo agregas al elemento 'content' que tienes en tu html
       document.getElementById('content').appendChild(newTemplate);

       // Ahora creamos otra variable para volver a usar el template
       const newTemplate2 = template.content;

       // Si haces un console.log de este newTemplate2 te devolvera null, ya que en la primera variable creada, has usado y modificado directamente el template.
       // Al newTemplate2 ser null, la operacion falla.
       newTemplate2.querySelector('h2').textContent = 'hola2';
       newTemplate2.querySelector('p').textContent = 'texto2';

       // Aqui lo intentas agregar a un nuevo elemento 'content2', pero no se mostrara por la falla anterior.
       document.getElementById('content2').appendChild(newTemplate2);

El html es este:

<template id="template">
       <h2></h2>
       <p></p>
</template>
<div id="content"></div>
<div id="content2"></div>

En este ejemplo, si ahora modificamos const newTemplate = template.content y const newTemplate2 = template.content por const newTemplate = template.content.cloneNode(true) y const newTemplate2 = template.content.cloneNode(true) respectivamente, veras que todo funciona correctamente y se ha reutilizado lo que contenia document.fragment

Avatar

@germanbaena67846

Angel, mil y mil gracias por tu excelente explicación, ya pude entender a cabalidad el ejercicio correspondiente a esta sección del curso. Quiero añadir lo siguiente, espero ser acertado en mi apreciación; de igual manera recibo todas las observaciones pertinentes a mis comentarios. Nuevamente Gracias.

const newTemplate = template.content, tiene el contenido del DocumentFragment en memoria hasta que se inserta en el DOM a través de appendChild(), después newTemplate queda vacío.

A estas alturas newTemplate = template.content = vacío, por eso si declaramos otra constante, ejemplo, const newTemplate2 = template.content, lo que realmente estamos declarando es newTemplate2 = vacio; en este punto si hago un console.log(newTemplate2), no me genera un null, muestra por consola #document-fragment, pero vacío; el null se genera cuando el navegador lee las siguientes líneas y aplica querySelector y texcontent a una constante vacía.

newTemplateDos.querySelector('h2').textContent = 'Hola' newTemplateDos.querySelector('p').textContent = 'Esto es una prueba'

Si pudiera decirlo en palabras casuales, la expresión template.content, no tiene la capacidad de recargar el contenido del <template> una vez es insertado su contenido en el DOM, a diferencia de la expresión template.content.cloneNode(true), la cual puede ser asignada una y otra vez a otras variables o constantes y ser insertado su contenido dentro de diferentes elementos html . El trabajo lo hace el método cloneNode().

Avatar

@angelsalvador

Exactamente German, buena voz! Me corregiste en el tema del null. Este null ocurre cuando se intenta aplicar los querySelector a un template.content que ya esta vació por haber sido modificado e insertado y por lo tanto no se podría hacer la reutilización del código, que es la idea del template. Es por ello que se hace la "clonación" con cloneNode().

Avatar

@germanbaena67846

Angel, ante todo, sin tu valiosa colaboración no hubiera llegado fácilmente hasta este punto, me llevaste de la mano para entender este concepto; se ve que has trabajado bastante sobre estos temas. Una pequeña observación: El simple hecho de insertar inicialmente el contenido de newTemplate en el DOM, o sea las etiquetas h2 y p peladitas, sin necesidad de modificarlas con la propiedad texcontent, hace que newTemplate quede vacía, y por consiguiente a través de template.content ya no se pueda recargar otra constante para reutilizar el DocumentFragment sin la ayuda de clone(node)

Avatar

@germanbaena67846

cloneNode(), correción a mi comentario final.

Avatar

@angelsalvador

Exactamente German, el hecho de insertar el template.content tal cual, así no se modifique nada de lo que se encuentra dentro, igualmente al momento de usarlo por segunda ves en una nueva variable, ocurrirá el error por estar vacía.

No lo creas, no tengo mucha experiencia, se podría decir que los 7 meses que llevo en EDTeam, leyendo documentación por cuenta propia y haciendo proyectos personales en todo ese tiempo, seria mi experiencia.

Recuerdainiciar sesiónpara participar en la comunidad.