javascript - tablas - innerhtml
¿La mejor manera de crear grandes elementos DOM estáticos en JavaScript? (5)
Puede intentar hacer una búsqueda AJAX del bloque HTML estático en lugar de almacenarlo en la página misma. Le permite ser más flexible con el tipo de bloque que desea insertar en el futuro también.
Alternativamente (esto es solo una idea aleatoria que no está muy bien formulada), puede almacenar la "estructura" como datos JSON y luego analizarla dinámicamente. Posiblemente algo como {"div": {"div": {"span": "Text here"}}}
para <div><div><span>Text here</span></div></div>
. Aun así, seguiré con AJAX. :)
Tengo muchos elementos que uno de mis widgets JS necesita crear y agregar al DOM a menudo. Ellos nunca cambian
Entonces, una opción sería almacenar el HTML como una cadena en JS y usar JQuery para crear los elementos a partir de la cadena, y luego anexarlo al documento:
var elements = "<div><table><tr><td>1</td><td>2</td></tr></table></div>";
function create() {
return $(elements);
}
$("body").append(create());
Otra opción es escribir una función que usará document.createElement ("div"), o $ ("<div>") muchas veces para construir los elementos, anexarlos cuando sea necesario, y luego anexar al documento:
function create() {
return $("<div>").append($("<table>")......
}
$("body").append(create());
En el primer caso, tengo una gran cadena JS que en realidad es HTML. En el segundo caso, tengo una pieza difícil de JS que realmente representa HTML.
¿Hay (des) ventajas para uno u otro? ¿Hay una mejor solución en la que no estoy pensando?
Si buscas rendimiento, me quedaré con la primera versión porque en la segunda cada vez que llamas $(''<div>'')
o $(''<table>'')
estás creando un nuevo Objeto jQuery y luego llamas .append()
que también hace otra llamada al método.
Yo iría con el primero.
Ya te respondiste a ti mismo.
EDITAR: muestra incorrecta borrada.
O hay otra opción, puedes poner el HTML directamente en el html actual dentro de div oculto como este:
<div id="hiddenContainer" style="display:none;">
<div><table><tr><td>1</td><td>2</td></tr></table></div>
</div>
Y luego en jquery, puedes leerlo:
var elements = $("#hiddenContainer").html()
Nota: Si odias la lectura, simplemente revisa el resumen a continuación para la respuesta final
Tal vez no necesites crearlos con la ayuda de jQuery.
Si la estructura de ese html es complicada (de ahí que usar el enfoque document.createElement sería una exageración) iría con el atributo innerHTML
.
// somewhere in your code, preferably outside of global scope
var div = document.createElement(''div'')
div.id = ''mycustomdiv''
document.getElementsByTagName(''body'')[0].appendChild(div);
// assuming elements contains string of html with your elements
div.innerHTML = elements;
De esta forma evitará la (innecesaria) sobrecarga adicional de crear y envolver los elementos en el objeto jQuery.
Actualización: prueba tú mismo cuál es el método más rápido http://jsperf.com/creating-complex-elements . Esta prueba confirma que cuando intentas exprimir hasta el último pedacito de rendimiento, revierte a javascript vainilla y operaciones DOM clásicas.
Actualización 2. Para investigar por qué el método innerHTML en Firefox 10 tiene tan malos resultados en relación con pasar cadena completa a jQuery.append, eché un vistazo a la fuente de jQuery.
Resulta que (en jQuery 1.7.1), están utilizando otra forma de crear elementos dom mediante la utilización de document.createDocumentFragment (con algunos inconvenientes, por supuesto, para los navegadores que no cuentan con el soporte adecuado).
DocumentFragments son DOM Nodes. Ellos nunca son parte del árbol DOM principal. El caso de uso habitual es crear el fragmento de documento, agregar elementos al fragmento de documento y luego anexar el fragmento de documento al árbol DOM. En el árbol DOM, el fragmento de documento se reemplaza por todos sus elementos secundarios.
Como el fragmento del documento está en la memoria y no es parte del árbol DOM principal, agregar hijos a él no causa el reflujo de la página .
Asumiendo que createDocumentFragment esté disponible, resulta ser el mejor enfoque en términos de rendimiento de script global entre navegadores.
Así que para resumir:
Estoy corregido. Si está buscando el mejor rendimiento en diferentes navegadores al crear nuevos elementos DOM, concéntrese en los fragmentos del documento (use jQuery si no quiere tratar con varios casos de esquina por su cuenta).
Para obtener más información sobre documentFragment, consulte esta publicación en el blog de John Resig http://ejohn.org/blog/dom-documentfragments/
Análisis detallado de 3 formas comunes de crear DOM en JS y el mejor enfoque.
Proporcionaré 3 formas de crear grandes DOM y sus pros y contras, y por supuesto la forma más optimizada para la creación de DOM de gran tamaño y por qué. En pocas palabras, al crear DOM en js, los métodos nativos JS y DOM son su amigo, no use Jquery a menos que no haya otra forma (lo cual es poco probable).
Datos de prueba para comparación: Creó 400 filas con 5 columnas y se agregó a DOM. TestData es una lista de objetos que obtienes desde el back-end en formato json para crear la tabla.
Exit de resultados de la prueba de tiempo de ejecución adjunta para diferentes navegadores HTML
<div id="employeeListContainer1"></div>
<table id="employeeList2">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Title</th>
<th>ID</th>
<th>Department</th>
</tr>
</thead>
1st way: Concatenación de cadenas (forma más optimizada en términos de rendimiento en los navegadores)
var tableElementContainer1 = document.getElementById("employeeListContainer1"),
temptableHolder = ''<table><thead><tr><th>First Name</th><th>Last Name</th><th>Title</th><th>ID</th><th>Department</th></tr></thead><tbody>'';
for(var i=0,len=testData.length; i<len; i++){
temptableHolder += ''<tr><td>'' + testData[i].firstName + ''</td><td>'' + testData[i].lastName + ''</td><td>'' + testData[i].title
+ ''</td><td>'' + testData[i].id + ''</td><td>'' + testData[i].department + ''</td></tr>'';
}
temptableHolder += ''</tbody></table>'';
tableElementContainer1.innerHTML = temptableHolder ;
Pros: - El tiempo de ejecución más rápido en Firefox / Chrome / IE / Safari (de 3 a 5 milisegundos en todos los navegadores) . Medido a través de las API de performance.now () y console.time ().
Contras: - Cuando el número de columnas es mayor y necesita establecer muchos atributos, trabajar con cadenas puede ser un poco difícil y menos sostenible.
2nd way: Native Js document.createElement () (Este es el segundo mejor enfoque en términos de rendimiento en navegadores)
var tableBody = document.createElement(''tbody''),
tableElement2 = document.getElementById("employeeList2"),
for(var i=0,len=testData.length; i<len; i++){
tableRow = document.createElement("tr");
for(var k in testData[i]){
rowCell = document.createElement("td");
rowCell.appendChild(document.createTextNode(testData[i][k]));
tableRow.appendChild(rowCell);
}
tableBody.appendChild(tableRow);
}
tableElement2.appendChild(tableBody);
Pros: - 2º tiempo de ejecución más rápido en Firefox / Chrome / Safari (de 5 a 12 milisegundos en todos los navegadores) . Medido a través de las API de performance.now () y console.time (). - Más principal defendible que 1er enfoque
Contras: - El tiempo de ejecución es más en los navegadores IE, más de 90 milisegundos
3rd Way: Usar Jquery para crear DOM (Mi consejo es no usarlo)
var tableBody = $(''<tbody></tbody>''),
tableElement2 = document.getElementById("employeeList2"),
for(var i=0,len=testData.length; i<len; i++){
tableRow = $("<tr></tr>");
for(var k in testData[i]){
rowCell = $("<td></td>");
rowCell.append(testData[i][k]);
tableRow.append(rowCell);
}
tableBody.append(tableRow);
}
tableElement2.append(tableBody);
Pros: - Fácil de agregar atributos / clase / estilos en los elementos y es fácil de leer y conservable.
Contras: - El peor tiempo de ejecución en todos los navegadores (220 ms a 330 ms) , los números más lentos están en IE