Chrome / jQuery Uncaught RangeError: Ukuran tumpukan panggilan maksimum terlampaui

113

Saya mendapatkan pesan kesalahan "Tidak Tertangkap RangeError: Ukuran tumpukan panggilan maksimum terlampaui" di chrome. di sini adalah fungsi jQuery saya

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

Perhatikan bahwa ada puluhan ribu sel di halaman. Namun, saya biasanya mengasosiasikan stack overflows dengan rekursi dan dalam kasus ini sejauh yang saya lihat tidak ada.

Apakah membuat lambda seperti ini secara otomatis menghasilkan banyak barang di tumpukan? apakah ada jalan lain untuk itu?

Saat ini satu-satunya solusi yang saya miliki adalah menghasilkan peristiwa onclick secara eksplisit di setiap sel saat merender HTML, yang membuat HTML jauh lebih besar.

Andy
sumber
2
Apakah Anda yakin fungsi foo tidak muncul kembali? Apakah kesalahan masih terjadi jika Anda menghapus panggilan fungsi itu?
Sth
1
Apakah ini berfungsi seperti yang diharapkan di browser lain? Apakah kesalahan ini terjadi saat Anda mengomentari foo($('#docId').val(), $(this).attr('id'));baris? - Tip kinerja ekstra: simpan hasil penyeleksi dalam cache - misalnya simpan hasil $(this)dalam variabel dan gunakan di seluruh handler sesuai kebutuhan.
WTK
Saya memiliki masalah serupa tetapi perlu acara mouseenter. Saat menggunakan tubuh atau tabel saya tidak mendapatkan cukup acara.
ericslaw

Jawaban:

133

Karena "ada puluhan ribu sel di halaman" yang mengikat peristiwa klik ke setiap sel akan menyebabkan masalah performa yang buruk. Ada cara yang lebih baik untuk melakukan ini, yaitu mengikat peristiwa klik ke badan & kemudian mencari tahu apakah elemen sel adalah target klik. Seperti ini:

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

Metode ini tidak hanya akan melakukan tugas Anda dengan tag "td" asli tetapi juga dengan "td" yang kemudian ditambahkan. Saya rasa Anda akan tertarik dengan artikel ini tentang event binding & delegate


Atau Anda cukup menggunakan metode " .on () " dari jQuery dengan efek yang sama:

$('body').on('click', 'td', function(){
        ...
});
vantrung -cuncon
sumber
terima kasih, kami sedang berjuang untuk kinerja dalam hal ini, jadi ini adalah ide yang bagus :-)
Andy
60
Tidak, jangan gunakan .live () !!! bitovi.com/blog/2011/04/… Gunakan .delegate () (atau .on () jika jQuery Anda cukup baru), dan delegasikan dari tingkat tabel daripada seluruh dokumen. Itu akan meningkatkan kinerja Anda lebih dari sekadar menggunakan .live (), yang pada dasarnya hanya akan mendelegasikan dari seluruh dokumen ke bawah.
brandwaffle
19
Dan .live telah dihapus dari jQuery 1.9
cpuguy83
37

Anda juga bisa mendapatkan kesalahan ini jika Anda memiliki loop tak terbatas. Pastikan Anda tidak memiliki referensi diri rekursif yang tak ada habisnya.

John Durden
sumber
6
Itu memecahkan masalah saya. Saya sudah punya <a id="linkDrink" onclick="drinkBeer();">Drink</a>, dan $('#linkDrink').click();masuk drinkBeer().
Aycan Yaşıt
7

Milik saya lebih merupakan kesalahan, yang terjadi adalah klik loop (saya kira) pada dasarnya dengan mengklik login orang tua juga diklik yang akhirnya menyebabkan ukuran tumpukan panggilan maksimum terlampaui.

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

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

Masalah ini terjadi pada saya ketika saya menggunakan jQUery Fancybox di dalam situs web dengan banyak plugin jQuery lainnya. Ketika saya menggunakan LightBox ( situs di sini ) daripada Fancybox, masalahnya hilang.

Silvio Delgado
sumber
1

Anda bisa menggunakan

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

Saya baru-baru ini mengalami masalah ini juga. Saya memiliki tabel yang sangat besar di div dialog. Itu> 15.000 baris. Ketika .empty () dipanggil pada dialog div, saya mendapatkan kesalahan di atas.

Saya menemukan solusi bulat di mana sebelum saya memanggil pembersihan kotak dialog, saya akan menghapus setiap baris lainnya dari tabel yang sangat besar, lalu memanggil .empty (). Sepertinya itu berhasil. Tampaknya JQuery versi lama saya tidak dapat menangani elemen sebesar itu.

dev4life
sumber