obtener ejemplos ejemplo div contenido con agregar javascript jquery html browser

ejemplos - obtener contenido de un div javascript



¿Por qué debería y.innerHTML=x.innerHTML; ser evitado? (6)

  1. Puede duplicar los ID que deben ser únicos.
  2. El método de clonación de jQuery hace call like, $(element).clone(true); clonará datos y oyentes de eventos, pero los ID también serán clonados. Por lo tanto, para evitar ID duplicados, no use ID para los elementos que necesitan ser clonados.

Digamos que tenemos un DIV x en la página y queremos duplicar ("copiar y pegar") el contenido de ese DIV en otro DIV y . Podríamos hacer esto así:

y.innerHTML = x.innerHTML;

o con jQuery:

$(y).html( $(x).html() );

Sin embargo, parece que este método no es una buena idea y que debe evitarse.

(1) ¿Por qué debería evitarse este método?

(2) ¿Cómo debe hacerse esto?

Actualizar:
Por el bien de esta pregunta, supongamos que no hay elementos con ID dentro de DIV x .
(Perdón, olvidé cubrir este caso en mi pregunta original).

Conclusión:
He publicado mi propia respuesta a esta pregunta a continuación (como originalmente pensé). Ahora, también planeé aceptar mi propia respuesta :P , pero la respuesta de un solo día es tan sorprendente que tengo que aceptarla en su lugar.


  1. Debe evitarse porque luego pierde cualquier controlador que pueda haber estado en ese elemento DOM.

  2. Puede tratar de evitar eso agregando clones de los elementos DOM en lugar de sobreescribirlos por completo.


Bueno, realmente depende. Existe la posibilidad de crear elementos duplicados con la misma ID, lo que nunca es bueno.

jQuery también tiene métodos que pueden hacer esto por ti.


Este método de "copiar" elementos HTML de un lugar a otro es el resultado de una interpretación errónea de lo que hace un navegador. Los navegadores no guardan un documento HTML en la memoria en algún lugar y modifican el HTML repetidamente en función de los comandos de JavaScript.

Cuando un navegador primero carga una página, analiza el documento HTML y lo convierte en una estructura DOM. Esta es una relación de objetos que sigue un estándar W3C (bueno, principalmente ...). El HTML original es desde entonces completamente redundante. Al navegador no le importa cuál era la estructura HTML original; su comprensión de la página web es la estructura DOM que se creó a partir de ella. Si su marcado HTML fue incorrecto / inválido, será corregido de alguna manera por el navegador web; la estructura DOM no contendrá el código inválido de ninguna manera.

Básicamente, HTML debe tratarse como una forma de serializar una estructura DOM que se pasará por Internet o se almacenará en un archivo localmente.

Por lo tanto, no debe usarse para modificar una página web existente. El DOM (Document Object Model) tiene un sistema para cambiar el contenido de una página. Esto se basa en la relación de los nodos, no en la serialización HTML. Entonces, cuando agrega un li a un ul , tiene estas dos opciones (suponiendo que ul es el elemento de la lista):

// option 1: innerHTML ul.innerHTML += ''<li>foobar</li>''; // option 2: DOM manipulation var li = document.createElement(''li''); li.appendChild(document.createTextNode(''foobar'')); ul.appendChild(li);

Ahora, la primera opción parece mucho más simple, pero esto es solo porque el navegador ha abstraído mucho para usted: internamente, el navegador tiene que convertir los elementos del elemento secundario en una cadena, luego agregar un contenido y luego convertir la cadena de nuevo a una estructura DOM. La segunda opción corresponde a la comprensión nativa del navegador de lo que está sucediendo.

La segunda consideración principal es pensar en las limitaciones de HTML. Cuando piensas en una página web, no todo lo relevante para el elemento se puede serializar a HTML. Por ejemplo, manejadores de eventos vinculados con x.onclick = function(); o x.addEventListener(...) no se replicará en innerHTML , por lo que no se copiarán. Entonces los nuevos elementos en y no tendrán los oyentes del evento. Esto probablemente no es lo que quieres.

Entonces, la forma de solucionar esto es trabajar con los métodos DOM nativos:

for (var i = 0; i < x.childNodes.length; i++) { y.appendChild(x.childNodes[i].cloneNode(true)); }

Leer la documentación de MDN probablemente ayudará a comprender esta forma de hacer las cosas:

Ahora el problema con esto (como con la opción 2 en el ejemplo de código anterior) es que es muy detallado, mucho más largo de lo que sería la opción innerHTML . Aquí es cuando aprecia tener una biblioteca de JavaScript que hace este tipo de cosas por usted. Por ejemplo, en jQuery:

$(''#y'').html($(''#x'').clone(true, true).contents());

Esto es mucho más explícito sobre lo que quiere que suceda. Además de tener varios beneficios de rendimiento y preservar los manejadores de eventos, por ejemplo, también le ayuda a comprender qué está haciendo su código. ¡Esto es bueno para tu alma como programador de JavaScript y hace que los errores extraños sean significativamente menos probables!


No lo haría simplemente porque le está pidiendo al navegador que vuelva a analizar el marcado HTML que ya ha sido analizado.

Estaría más inclinado a usar el cloneNode(true) nativo cloneNode(true) para duplicar los elementos DOM existentes.

var node, i=0; while( node = x.childNodes[ i++ ] ) { y.appendChild( node.cloneNode( true ) ); }


Primero, definamos la tarea que se debe realizar aquí:

Todos los nodos secundarios de DIV x tienen que ser "copiados" (junto con todos sus descendientes = copia profunda) y "pegados" en el DIV y . Si alguno de los descendientes de x tiene uno o más controladores de eventos vinculados a él, presumiblemente queremos que esos manejadores continúen trabajando en las copias (una vez que se han colocado dentro de y ).

Ahora, esta no es una tarea trivial. Afortunadamente, la biblioteca de jQuery (y todas las demás bibliotecas populares, supongo) ofrece un método conveniente para realizar esta tarea: .clone() . Usando este método, la solución podría escribirse así:

$( x ).contents().clone( true ).appendTo( y );

La solución anterior es la respuesta a la pregunta (2). Ahora, abordemos la pregunta (1):

Esta

y.innerHTML = x.innerHTML;

no es solo una mala idea, es horrible. Dejame explicar...

La declaración anterior se puede dividir en dos pasos.

  1. La expresión x.innerHTML se evalúa,

  2. Ese valor de retorno de esa expresión (que es una cadena) se asigna a y.innerHTML .

Los nodos que queremos copiar (los nodos secundarios de x ) son nodos DOM. Son objetos que existen en la memoria del navegador. Al evaluar x.innerHTML , el navegador serializa (stringifica) esos nodos DOM en una cadena (cadena de código fuente HTML).

Ahora, si necesitábamos una cadena (para almacenarla en una base de datos, por ejemplo), esta serialización sería comprensible. Sin embargo, no necesitamos esa cadena (al menos no como producto final).

En el paso 2, estamos asignando esta cadena a y.innerHTML . El navegador evalúa esto al analizar la cadena que da como resultado un conjunto de nodos DOM que luego se insertan en DIV y (como nodos secundarios).

Así que para resumir:

Nodos secundarios de x -> encadenamiento -> código fuente HTML cadena -> análisis -> Nodos (copias)

Entonces, ¿cuál es el problema con este enfoque? Bueno, los nodos DOM pueden contener propiedades y funcionalidades que no pueden y, por lo tanto, no se serializarán . La funcionalidad más importante es la de los manejadores de eventos que están ligados a descendientes de x - las copias de esos elementos no tendrán ningún manejador de eventos ligado a ellos. Los controladores se perdieron en el proceso.

Una analogía interesante se puede hacer aquí:

Señal digital -> Conversión D / A -> Señal analógica -> Conversión A / D -> Señal digital

Como probablemente sepa, la señal digital resultante no es una copia exacta de la señal digital original; parte de la información se perdió en el proceso.

Espero que entiendas ahora por qué y.innerHTML = x.innerHTML debe evitarse.