eliminar - obtener id de un elemento javascript
Cómo eliminar elementos DOM sin pérdidas de memoria? (5)
Mi código JavaSript crea una lista de elementos LI
. Cuando actualizo la lista, el uso de memoria crece y nunca baja. Probé en sIEve y muestra que el navegador mantiene todos los elementos que se suponía que debían eliminarse con $.remove()
o $.empty
jQuery.
¿Qué debo hacer para eliminar los nodos DOM sin la pérdida de memoria?
Ver mi otra pregunta para el código específico.
¿Has eliminado a los oyentes del evento? Eso puede causar pérdidas de memoria .
El DOM conserva todos los nodos DOM, incluso si se han eliminado del árbol DOM en sí, la única forma de eliminar estos nodos es hacer una actualización de página (si coloca la lista en un iframe, la actualización no será tan notoria)
De lo contrario, podría esperar a que el problema empeore lo suficiente como para que el recolector de basura de los navegadores se vea obligado a entrar en acción (hablando de cientos de megabytes de nodos no utilizados aquí)
La mejor práctica es reutilizar los nodos.
EDITAR: Prueba esto:
var garbageBin;
window.onload = function ()
{
if (typeof(garbageBin) === ''undefined'')
{
//Here we are creating a ''garbage bin'' object to temporarily
//store elements that are to be discarded
garbageBin = document.createElement(''div'');
garbageBin.style.display = ''none''; //Make sure it is not displayed
document.body.appendChild(garbageBin);
}
function discardElement(element)
{
//The way this works is due to the phenomenon whereby child nodes
//of an object with it''s innerHTML emptied are removed from memory
//Move the element to the garbage bin element
garbageBin.appendChild(element);
//Empty the garbage bin
garbageBin.innerHTML = "";
}
}
Para usarlo en tu contexto, lo harías así:
discardElement(this);
El código siguiente no se filtra en mi IE7 y otros navegadores:
<html>
<head></head>
<body>
<a href="javascript:" onclick="addRemove(this)">add</a>
<ul></ul>
<script>
function addRemove(a) {
var ul = document.getElementsByTagName(''UL'')[0],
li, i = 20000;
if (a.innerHTML === ''add'') {
while (i--) {
li = document.createElement(''LI'');
ul.appendChild(li);
li.innerHTML = i;
li.onclick = function() {
alert(this.innerHTML);
};
}
a.innerHTML = ''remove'';
} else {
while (ul.firstChild) {
ul.removeChild(ul.firstChild);
}
a.innerHTML = ''add'';
}
}
</script>
</body>
</html>
Puede ser que puedas tratar de detectar algunas diferencias con tu código.
Sé que IE pierde mucho menos cuando inserta primero el nodo en el DOM antes de hacer algo al respecto, por ejemplo: adjuntarle eventos o completar su propiedad innerHTML
.
Esto es más un FYI que una respuesta real, pero también es bastante interesante.
A partir de la especificación del núcleo W3C DOM (http://www.w3.org/TR/DOM-Level-2-Core/core.html):
Las API Core DOM están diseñadas para ser compatibles con una amplia gama de idiomas, incluidos los lenguajes de scripting de usuario general y los lenguajes más desafiantes utilizados principalmente por programadores profesionales. Por lo tanto, las DOM API necesitan operar en una variedad de filosofías de administración de memoria, desde enlaces de lenguaje que no exponen la administración de memoria al usuario, pasando por aquellos (especialmente Java) que proporcionan constructores explícitos pero proporcionan un mecanismo automático de recolección de basura para automáticamente reclamar memoria no utilizada, a aquellos (especialmente C / C ++) que generalmente requieren que el programador asigne explícitamente memoria de objeto, rastrear dónde se usa y liberarla explícitamente para su reutilización. Para garantizar una API consistente en todas estas plataformas, el DOM no aborda en absoluto los problemas de administración de memoria, sino que los deja para la implementación. Ninguno de los enlaces de lenguaje explícitos definidos por la DOM API (para ECMAScript y Java) requieren ningún método de gestión de memoria, pero los enlaces DOM para otros lenguajes (especialmente C o C ++) pueden requerir tal soporte. Estas extensiones serán responsabilidad de quienes adaptan la DOM API a un idioma específico, no al Grupo de trabajo DOM.
En otras palabras: la administración de la memoria se deja a la implementación de la especificación DOM en varios idiomas. Tendría que buscar en la documentación de la implementación DOM en javascript para encontrar cualquier método para eliminar un objeto DOM de la memoria, que no es un hack. (Sin embargo, hay muy poca información sobre el tema en el sitio de MDC).
Como nota sobre jQuery#remove
y jQuery#empty
: por lo que puedo decir, ninguno de estos métodos hace nada más que eliminar Object
s de los node
DOM o eliminar los node
DOM del document
.Solo eliminan Eso, por supuesto, no significa que no haya memoria asignada a estos objetos (aunque ya no estén en el document
).
Editar: El pasaje anterior era superfluo ya que obviamente jQuery no puede hacer maravillas y trabajar con la implementación DOM del navegador usado.
Si tiene que "posponer" la fuga, y debe hacerlo sin reescribir todo su código para tomar cierres, referencias circulares, etc. en la cuenta, utilice el método de limpieza Douglas Crockfords antes de eliminar:
http://javascript.crockford.com/memory/leak.html
O use esta solución alternativa de cierre: