2010-02-13 23 views
9

¿Qué técnica a continuación es mejor a partir de una experiencia de usuario?JavaScript: agregar hijos al elemento

En ambos ejemplos, suponga que thumbContainer se establece en el valor de retorno de document.getElementById('thumbContainer') y new Thumbnail(thumb).toXMLString() devuelve una cadena con marcado XHTML.

A) Simplemente += con thumbContainer.innerHTML:

for (thumb in thumbnails) { 
    thumbContainer.innerHTML += new Thumbnail(thumb).toXMLString(); 
} 

B) o la conversión de new Thumbnail(thumb).toXMLString() a elementos DOM y el uso de appendChild?

for (thumb in thumbnails) { 
    var shell = document.createElement('div'); 
    shell.innerHTML = new Thumbnail(thumb).toXMLString(); 
    for (i = 0; i < shell.childElementCount; i++) { 
     thumbContainer.appendChild(shell.children[i]); 
    } 
} 

He usado ambos y obtener las quejas de Firefox que tengo un guión de larga duración, y es lo que quiero para detenerlo?

¿Qué bucle es menos ajustado, que permitirá que la interfaz de usuario se actualice a medida que se agreguen nuevos elementos al DOM?

Respuesta

6

Personalmente, me gusta más el segundo enfoque (usando appendChild), porque está agregando un nuevo elemento al árbol de documentos sin afectar a los elementos antiguos.

Al usar innerHTML + = contenido nuevo, afecta el contenido anterior, porque todo el HTML debe reasignarse (reemplazado por un nuevo código HTML que contiene un código antiguo y un código nuevo).

Pero, si desea aumentar el rendimiento, le sugiero que utilice DocumentFragments. Utilizándolos puede agregar un conjunto completo de nodos con solo una llamada appendChild en el árbol de documentos. Vale la pena leerlo: "DOM DocumentFragments" by John Resig, pero no es el caso en su problema, porque obtiene el contenido como una cadena, que primero debe convertir a nodos DOM.

Mi segunda sugerencia es, para crear una cadena de código HTML y luego usar innerHTML en un contenedor temporal para convertirlo en DOM nodos

var htmlCode = ""; 
for (thumb in thumbnails) { 
    htmlCode += new Thumbnail(thumb).toXMLString(); 
} 
var element = document.createElement(htmlCode); 
element.innerHTML = htmlCode; // ... and append all the elements to document, or thumbContainer.innerHTML += htmlCode; 
+0

Espero que su ejemplo no funcione, ya que 'Thumbnail # toXMLString' * devuelve una cadena con marcado XHTML *. Por lo tanto, el nombre de etiqueta proporcionado en 'document.createElement (htmlCode)' no es un nombre válido. – yckart

10

A) + = Simplemente con thumbContainer.innerHTML

Nunca haga esto. Esto tiene que serializar todo el contenido en HTML, agregarle una cadena y analizarlo todo de nuevo. Es lento (hacerlo en un bucle es particularmente malas noticias) y perderá todas las referencias de JavaScript, controladores de eventos, etc. .

IE insertAdjacentHTML hará esto de manera más eficiente. También es parte de HTML5, pero aún no se ha implementado ampliamente en otros lugares.

usando appendChild?

Sí, está bien. Si tiene un lote de pulgares comenzará a ralentizarse (pero no tan mal como repasando innerHTML cada vez). Hacer un Fragmento de documento para insertar múltiples elementos en la lista de nodos secundarios de contenedor a la vez puede ayudar en algunos casos. La combinación de DocumentFragment con Range puede hacer aún más, pero es más difícil escribir de manera compatible ya que la implementación de Range de IE es tan StRange.

De cualquier manera, ya que no parece estar haciendo nada con los nodos de shell individuales, ¿por qué no simplemente unir todas las cadenas de HTML en conjunto antes de analizar?

para (var niño en shell.childNodes) {

No utilice for..in de tipos de secuencias, no va a hacer lo que usted piensa. Solo debe usarse contra Object como mapeo. La forma correcta de iterar sobre un Array o NodeList es simple viejo for (var i= 0; i<sequence.length; i++).

+2

+1, de acuerdo en todos los puntos (como de costumbre). –

+0

Gracias por el 'insertAdjacentHTML'. Eso es lo que necesitaba – w35l3y

Cuestiones relacionadas