2012-06-06 8 views
7

Sin entrar en demasiados detalles, estoy limpiando los espacios en blanco dentro de las tablas usando javascript. Necesito eliminar grandes cantidades de textnodes. Este parece ser el cuello de botella en mi script cuando se trata de IE9.Eliminando eficientemente los nodos de texto del DOM

Todos los siguientes métodos hacen el trabajo, pero causan una enorme desaceleración.

domNode.removeNode(true); 
domNode.nodeValue = ""; 
domNode.parentNode.removeChild(domNode); 

Hay una manera de hacer una eliminación a granel o una manera de ocultarlos en el dom o tal. Solo algo más rápido.

También he intentado esto en los textnodes:

domNode.innerHTML = ''; 

Mientras se ejecuta rápidamente, los textnodes parecen ser unphased por ella.

Además, tengo que conservar los enlaces de eventos para que un .innerHTML reemplazar en toda la tabla realmente no parezca una opción. Aunque funciona aproximadamente 5 veces más rápido.

Actualización: puntos de referencia Rough en soluciones sugeridas:

//around 480ms 
stripWhitespaceTextNodes(domNode); 

//around 640ms 
parent.removeChild(domNode); 
stripWhitespaceTextNodes(domNode); 
parent.insertBefore(domNode, nextNode); 

//around 700ms 
tables[i].style.visibility = 'hidden'; 
stripWhitespaceTextNodes(domNode); 
tables[i].style.visibility = 'visible'; 

//around 1140ms 
tables[i].style.display = 'none'; 
stripWhitespaceTextNodes(domNode); 
tables[i].style.display = 'block'; 

Esto se hizo en 4 mesas con una tabla que tiene 1500 filas.

El quid de la función stripWhitespaceTextNodes() es la eliminación de los nodos de texto, esto parece ser el cuello de botella y aquí están mis varios intentos de hacerlo.

domNode.parentNode.removeChild(domNode); 
domNode.removeNode(true); 
domNode.nodeValue = ""; // <-- CURRENTLY THIS ONE IS THE TOP RUNNER 
domNode.replaceWholeText(''); 
domNode.deleteData(0, domNode.length); 

var txtNode = document.createTextNode(""); 
domNode.parentNode.replaceChild(txtNode, domNode); 
parent.insertBefore(domNode, nextNode); 

//fast but doesn't work 
domNode.innerHTML = ''; 
+0

Me interesarían los detalles. ¿Por qué necesita eliminar whitespace-textNodes de una tabla, no afectarán la visualización? – Bergi

+0

Lo hacen en IE9. Refiérase a esta pregunta para esos detalles. http://stackoverflow.com/questions/9895095/wanted-ie9-table-cell-ghost-alive-and-without-js En cuanto a por qué no puedo arreglarlo en el lado del servidor, esa es otra historia larga. .. – Serhiy

+0

¿Has intentado utilizar domNode.innerText = '' o domNode.textContent = '' para eliminar los nodos de texto? – tjscience

Respuesta

0

Una manera de hacerlo es clonar toda la tabla y hacer manipulaciones "fuera del lugar". Significa hacer las operaciones al clon donde el clon no está en el DOM. Después, haga una sola sustitución de la tabla completa con el clon modificado. De esa forma, las operaciones no se estancarán.

Here's an answer que se refiere a varios métodos para "clonar" el DOM y crear "elementos de contenedor" para operaciones fuera del DOM.

+0

Puede haber saltado la pistola en la suposición de redibujado DOM. Crear un domNode clonado y trabajar con eso no aparece más rápido. Parece que las herramientas de manipulación domNode de IE pueden ser tan lentas. – Serhiy

6

El truco habitual para esto es eliminar el contenedor en el que realiza estas operaciones desde el DOM antes de realizar los grandes cambios, y luego volver a colocarlo cuando haya terminado.

Así, en su caso, que podría ser:

var table = /* ...get a reference to the table...*/; 
var nextNode = table.nextSibling; // May be null, that's fine 
var parent = table.parentNode; 
parent.removeChild(table); 
/* ...clean up the text nodes... */ 
parent.insertBefore(table, nextNode); 

Los controladores de eventos permanecen unidos incluso cuando el árbol se separa del DOM de la página, así que estarán allí cuando el árbol se vuelve a poner.

+0

Si solo quiere evitar las repintaciones, 'table.style.display =" none "' debería ser suficiente. – Bergi

+0

@Bergi: No tanto re * pinta * como re * flows *. Pero sí, absolutamente, el OP debería tratar de hacer que la tabla no se muestre tan bien como la anterior, y elegir la que funcione mejor para él/ella. –

+0

¿Dónde está la diferencia? Seguramente, podría haber reflujos sin repintados cuando js calcula con valores CSS, no aquí, pero ninguno de ellos debería pasar a elementos ocultos. – Bergi

0

Puede intentar separar su tabla (elemento DOM de tabla) del documento, caminar sobre ella y eliminar los nodos de texto en blanco como lo hace, y luego insertar la tabla en la posición original. En teoría, debería ganar velocidad: Render Tree no necesitaría actualizarse en cada pase, lo que es costoso para las tablas de los documentos.

+0

Gracias por la sugerencia, eso es lo que estaba pensando/esperando. Sin embargo, cuando realicé pruebas, trabajar en tablas eliminadas del DOM en realidad fue más lento. No tiene sentido, pero ese es el resultado que obtuve. – Serhiy

Cuestiones relacionadas