Chrome / jQuery Uncaught RangeError: dimensione massima dello stack di chiamate superata


113

Ricevo l'errore "Errore di intervallo non rilevato: dimensione massima dello stack di chiamate superata" su Chrome. ecco la mia funzione jQuery

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

Nota che ci sono decine di migliaia di celle nella pagina. Tuttavia, generalmente associo gli stack overflow alla ricorsione e in questo caso per quanto posso vedere non ce n'è.

La creazione di un lambda come questo genera automaticamente un carico di cose nello stack? c'è un modo per aggirarlo?

Al momento l'unica soluzione che ho è generare gli eventi onclick esplicitamente su ogni cella durante il rendering dell'HTML, il che rende l'HTML molto più grande.


2
Sei sicuro che la funzione foo non si ripeta? L'errore si verifica ancora se rimuovi quella chiamata di funzione?
sth

1
Funziona come previsto in altri browser? Questo errore si verifica quando si commenta la foo($('#docId').val(), $(this).attr('id'));riga? - Suggerimento per prestazioni extra: memorizza nella cache il risultato dei selettori, ad esempio mantieni il risultato di $(this)in una variabile e poi usalo nel tuo gestore secondo necessità.
WTK

Ho un problema simile ma ho bisogno di eventi mouseenter. Quando utilizzo body o table non ricevo abbastanza eventi.
ericslaw

Risposte:


133

Poiché "ci sono decine di migliaia di celle nella pagina", il collegamento dell'evento clic a ogni singola cella causerà un terribile problema di prestazioni. C'è un modo migliore per farlo, ovvero associare un evento clic al corpo e quindi scoprire se l'elemento della cella era l'obiettivo del clic. Come questo:

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

Questo metodo non solo eseguirà il tuo compito con il tag "td" nativo, ma anche con "td" aggiunto successivamente. Penso che ti interesserà questo articolo sull'associazione e il delegato di eventi


Oppure puoi semplicemente usare il metodo " .on () " di jQuery con lo stesso effetto:

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

grazie, stiamo comunque lottando per le prestazioni su questo, quindi questa è un'ottima idea :-)
Andy

60
Nooo, non usare .live () !!! bitovi.com/blog/2011/04/… Usa un .delegate () (o .on () se il tuo jQuery è abbastanza nuovo) e delega dal livello di tabella piuttosto che dall'intero documento. Ciò migliorerà le tue prestazioni molto più del semplice utilizzo di .live (), che essenzialmente delegherà solo l'intero documento verso il basso.
brandwaffle

19
E .live è stato rimosso da jQuery 1.9
cpuguy83

37

Puoi anche ricevere questo errore quando hai un ciclo infinito. Assicurati di non avere auto-referenze ricorsive e infinite.


6
Questo ha risolto il mio problema. Ho avuto un <a id="linkDrink" onclick="drinkBeer();">Drink</a>e un $('#linkDrink').click();in drinkBeer().
Aycan Yaşıt

7

Il mio è stato più un errore, quello che è successo è stato il clic del ciclo (immagino) fondamentalmente facendo clic sul login è stato fatto clic anche sul genitore che ha finito per causare il superamento della dimensione massima dello stack di chiamate.

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

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

3

Questo problema è accaduto con me quando ho usato jQUery Fancybox all'interno di un sito Web con molti altri plugin jQuery. Quando ho usato il LightBox ( sito qui ) invece di Fancybox, il problema è scomparso.


1

Puoi usare

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

0

Di recente ho riscontrato anche questo problema. Avevo una tabella molto grande nella finestra di dialogo div. Era> 15.000 righe. Quando è stato chiamato .empty () nella finestra di dialogo div, ho ricevuto l'errore sopra.

Ho trovato una soluzione rotonda in cui prima di chiamare la pulizia della finestra di dialogo, rimuovevo ogni altra riga dalla tabella molto grande, quindi chiamavo .empty (). Tuttavia sembrava aver funzionato. Sembra che la mia vecchia versione di JQuery non sia in grado di gestire elementi così grandi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.