Error de rango no detectado de Chrome / jQuery: se excedió el tamaño máximo de la pila de llamadas

113

Recibo el error "Error de rango no detectado: se excedió el tamaño máximo de la pila de llamadas" en Chrome. aquí está mi función jQuery

$('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 los desbordamientos de pila con la recursividad y, en este caso, por lo que puedo ver, no hay ninguno.

¿Crear una lambda como esta genera automáticamente una gran cantidad 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 al representar el HTML, lo que hace que el HTML sea mucho más grande.

Andy
fuente
2
¿Estás seguro de que la función foo no se repite? ¿Sigue ocurriendo el error si elimina esa llamada de función?
algo
1
¿Funciona como se esperaba en otros navegadores? ¿Ocurre este error cuando comenta la foo($('#docId').val(), $(this).attr('id'));línea? - Consejo de rendimiento adicional: almacene en caché el resultado de los selectores; por ejemplo, mantenga el resultado de $(this)en una variable y luego úselo en su controlador según sea necesario.
WTK
Tengo un problema similar pero necesito eventos de mouseenter. Cuando uso el cuerpo o la tabla, no obtengo suficientes eventos.
ericslaw

Respuestas:

133

Como "hay decenas de miles de celdas en la página", vincular el evento de clic a cada celda causará un terrible problema de rendimiento. Hay una mejor manera de hacer esto, que es vincular un evento de clic al cuerpo y luego averiguar si el elemento de la celda fue el objetivo del clic. Me gusta esto:

$('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 solo hará su tarea con la etiqueta "td" nativa, sino también con la "td" adjunta posteriormente. Creo que te interesará este artículo sobre vinculación y delegado de eventos


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

$('body').on('click', 'td', function(){
        ...
});
vantrung -cuncon
fuente
gracias, estamos luchando por el rendimiento en esto de todos modos, así que esta es una gran idea :-)
Andy
60
Nooo, no uses .live () !!! bitovi.com/blog/2011/04/… Use un .delegate () (o .on () si su jQuery es lo suficientemente nuevo), y delegue desde el nivel de tabla en lugar de todo el documento. Eso mejorará su rendimiento mucho más que simplemente usar .live (), que esencialmente solo delegará de todo el documento hacia abajo.
brandwaffle
19
Y .live se ha eliminado de jQuery 1.9
cpuguy83
37

También puede obtener este error cuando tiene un bucle infinito. Asegúrese de no tener referencias personales interminables y recursivas.

John Durden
fuente
6
Eso resolvió mi problema. He tenido un <a id="linkDrink" onclick="drinkBeer();">Drink</a>, y un $('#linkDrink').click();en drinkBeer().
Aycan Yaşıt
7

El mío fue más un error, lo que sucedió fue un clic en bucle (supongo) básicamente al hacer clic en el inicio de sesión, también se hizo clic en el padre, lo que terminó causando 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>
Jsonras
fuente
3

Este problema me sucedió cuando usé jQUery Fancybox dentro de un sitio web con muchos otros complementos de jQuery. Cuando usé LightBox ( sitio aquí ) en lugar de Fancybox, el problema desapareció.

Silvio Delgado
fuente
1

U puede usar

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

Recientemente también me encontré con este problema. Tenía una tabla muy grande en el diálogo div. Fue> 15.000 filas. Cuando se llamó a .empty () en el cuadro de diálogo div, recibí el error anterior.

Encontré una solución redonda en la que antes de llamar a limpiar el cuadro de diálogo, eliminaría todas las dos filas de la tabla muy grande y luego llamaría a .empty (). Sin embargo, parecía haber funcionado. Parece que mi versión anterior de JQuery no puede manejar elementos tan grandes.

dev4life
fuente