2011-10-05 8 views
94

Recibo el error "RangeError no capturado: el tamaño máximo de pila de llamadas excedido" en cromo. aquí está mi función jQueryChrome/jQuery Range Range no detectado: el tamaño máximo de pila de llamadas superó

$('td').click(function() { 
     if ($(this).context.id != null && $(this).context.id != '') { 
      foo($('#docId').val(), $(this).attr('id')); 
     } 
     return false; 
    }); 

Tenga en cuenta que hay decenas de miles de celdas en la página. Sin embargo, generalmente asocio desbordamientos de pila con recursión y en este caso, hasta donde puedo ver, no hay ninguno.

¿La creación de una lambda como esta genera automáticamente una carga de cosas en la pila? ¿Hay alguna forma de evitarlo?

Por el momento la única solución que tengo es generar los eventos onclick explícitamente en cada celda cuando se renderiza el HTML, lo que hace que el HTML sea mucho más grande.

+2

¿Estás seguro de que la función foo no se repite? ¿El error aún ocurre si elimina esa llamada de función? – sth

+1

¿Funciona como se esperaba en otros navegadores? ¿Se produce este error cuando comenta la línea 'foo ($ ('# docId'). Val(), $ (this) .attr ('id'));'? - Consejo de rendimiento extra: almacena en caché el resultado de los selectores; por ejemplo, guarda el resultado de '$ (this)' en una variable y luego utilízalo en tu controlador según sea necesario. – WTK

+0

Tengo un problema similar pero necesito eventos de mouseenter. Cuando uso el cuerpo o la mesa, no obtengo suficientes eventos. – ericslaw

Respuesta

113

Como "hay decenas de miles de celdas en la página", el enlace del evento de clic a cada celda provocará un terrible problema de rendimiento. Hay una forma mejor de hacerlo, que es vincular un evento de clic al cuerpo & y luego averiguar si el elemento de la celda era el objetivo del clic. De esta manera:

$('body').click(function(e){ 
     var Elem = e.target; 
     if (Elem.nodeName=='td'){ 
      //.... your business goes here.... 
      // remember to replace $(this) with $(Elem) 
     } 
}) 

Este método no sólo va a hacer su tarea con la etiqueta nativa "TD", sino también más adelante anexa "TD". Creo que usted estará interesado en este artículo sobre event binding & delegate


O puede simplemente usar el método ".on()" de jQuery con el mismo efecto:

$('body').on('click', 'td', function(){ 
     ... 
}); 
+0

gracias, estamos luchando por el rendimiento en esto de todos modos, así que esta es una gran idea :-) – Andy

+57

Nooo, no use .live() !!! http://bitovi.com/blog/2011/04/why-you-should-never-use-jquery-live.html Use un .delegate() (o .on() si su jQuery es lo suficientemente nuevo), y delegar desde el nivel de la mesa en lugar de todo el documento. Eso mejorará tu rendimiento mucho más que usar .live(), que básicamente solo delegará todo el documento. – brandwaffle

+17

Y .live se ha eliminado de jQuery 1.9 – cpuguy83

3

Este problema sucedió conmigo cuando utilizaba Ququy Fancybox dentro de un sitio web con muchos otros complementos jQuery. Cuando utilicé LightBox (site here) en lugar de Fancybox, el problema desapareció.

28

También puede obtener este error cuando tiene un bucle infinito. Asegúrate de no tener ninguna autoreferencia recursiva e interminable.

+3

Eso resolvió mi problema. He tenido un 'Drink', y un '$ ('# linkDrink'). Click();' en 'drinkBeer()'. –

4

El mío fue más un error, lo que sucedió fue un clic de bucle (supongo) básicamente al hacer clic en el inicio de sesión también se hizo clic en el padre que terminó provocando que se excediera el tamaño máximo de la pila de llamadas.

$('.clickhere').click(function(){ 
    $('.login').click(); 
}); 

<li class="clickhere"> 
    <a href="#" class="login">login</a> 
</li> 
1

U puede utilizar

$(document).on('click','p.class',function(e){ 
    e.preventDefault(); 
     //Code 
    }); 
0

Hace poco acabo de encontrar con este problema también. Tenía una mesa muy grande en el diálogo div. Fue> 15,000 filas. Cuando se invocó .empty() en el diálogo div, estaba obteniendo el error anterior.

Encontré una solución integral donde antes de llamar a limpiar el cuadro de diálogo, quitaba cada dos filas de la tabla muy grande, luego llamo a .empty(). Aunque parecía haber funcionado. Parece que mi versión anterior de JQuery no puede manejar elementos tan grandes.

Cuestiones relacionadas