Chrome / jQuery Uncaught RangeError: เกินขนาดสแต็กการโทรสูงสุด


113

ฉันได้รับข้อผิดพลาด "Uncaught RangeError: ขนาดสแต็กการโทรสูงสุดเกิน" บน Chrome นี่คือฟังก์ชั่น jQuery ของฉัน

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

สังเกตว่ามีเซลล์นับหมื่นในหน้า อย่างไรก็ตามโดยทั่วไปฉันเชื่อมโยงสแต็คล้นกับการเรียกซ้ำและในกรณีนี้เท่าที่ฉันเห็นไม่มีเลย

การสร้างแลมบ์ดาเช่นนี้จะทำให้เกิดภาระในสแตกโดยอัตโนมัติหรือไม่? มีวิธีใดบ้าง?

ในขณะนี้วิธีแก้ปัญหาเดียวที่ฉันมีคือการสร้างเหตุการณ์ onclick อย่างชัดเจนในแต่ละเซลล์เมื่อแสดงผล HTML ซึ่งทำให้ HTML มีขนาดใหญ่ขึ้นมาก


2
แน่ใจหรือไม่ว่าฟังก์ชัน foo ไม่ฟื้นคืนสภาพ? ข้อผิดพลาดยังคงเกิดขึ้นหรือไม่หากคุณลบการเรียกใช้ฟังก์ชันนั้น

1
ทำงานตามที่คาดไว้ในเบราว์เซอร์อื่นหรือไม่ ข้อผิดพลาดนี้เกิดขึ้นเมื่อคุณแสดงความคิดเห็นในfoo($('#docId').val(), $(this).attr('id'));บรรทัดหรือไม่ - เคล็ดลับประสิทธิภาพพิเศษ: แคชผลลัพธ์ของตัวเลือก - ตัวอย่างเช่นเก็บผลลัพธ์$(this)ไว้ในตัวแปรและใช้มากกว่าในตัวจัดการของคุณตามต้องการ
WTK

ฉันมีปัญหาที่คล้ายกัน แต่ต้องการ mouseenter events เมื่อใช้ร่างกายหรือโต๊ะฉันไม่ได้รับเหตุการณ์ที่เพียงพอ
ericslaw

คำตอบ:


133

เนื่องจาก "มีเซลล์หลายหมื่นเซลล์ในเพจ" การเชื่อมโยงเหตุการณ์การคลิกกับทุกเซลล์จะทำให้เกิดปัญหาด้านประสิทธิภาพที่แย่มาก มีวิธีที่ดีกว่าในการทำเช่นนี้นั่นคือการเชื่อมโยงเหตุการณ์การคลิกเข้ากับเนื้อหาแล้วดูว่าองค์ประกอบของเซลล์นั้นเป็นเป้าหมายของการคลิกหรือไม่ แบบนี้:

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

วิธีนี้จะไม่เพียง แต่ทำงานของคุณด้วยแท็ก "td" ดั้งเดิมเท่านั้น แต่ยังรวมถึง "td" ที่ต่อท้ายด้วย ฉันคิดว่าคุณจะสนใจบทความนี้เกี่ยวกับการผูกเหตุการณ์และผู้รับมอบสิทธิ์


หรือคุณสามารถใช้เมธอด" .on () " ของ jQuery ที่มีเอฟเฟกต์เดียวกัน:

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

ขอบคุณเรากำลังดิ้นรนเพื่อประสิทธิภาพในเรื่องนี้ดังนั้นนี่จึงเป็นความคิดที่ดี :-)
Andy

60
นู๋ไม่ใช้. live () !!! bitovi.com/blog/2011/04/…ใช้. delegate () (หรือ. on () ถ้า jQuery ของคุณใหม่พอ) และมอบหมายจากระดับตารางแทนที่จะเป็นทั้งเอกสาร ซึ่งจะช่วยปรับปรุงประสิทธิภาพของคุณได้มากกว่าการใช้. live () ซึ่งโดยพื้นฐานแล้วจะเป็นเพียงการมอบหมายจากเอกสารทั้งหมดลงไป
brandwaffle

19
และ. live ถูกลบออกจาก jQuery 1.9
cpuguy83

37

คุณยังสามารถรับข้อผิดพลาดนี้ได้เมื่อคุณมีการวนซ้ำแบบไม่สิ้นสุด ตรวจสอบให้แน่ใจว่าคุณไม่มีการอ้างอิงตัวเองซ้ำ ๆ ที่ไม่รู้จักจบสิ้น


6
นั่นช่วยแก้ปัญหาของฉันได้ ฉันมี<a id="linkDrink" onclick="drinkBeer();">Drink</a>และ$('#linkDrink').click();ในdrinkBeer().
Aycan Yaşıt

7

ของฉันมีข้อผิดพลาดมากกว่าสิ่งที่เกิดขึ้นคือการคลิกแบบวนซ้ำ (ฉันเดา) โดยพื้นฐานแล้วโดยการคลิกที่การเข้าสู่ระบบผู้ปกครองก็ถูกคลิกซึ่งทำให้เกิดการโทรสแต็กเกินขนาดสูงสุด

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

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



0

ฉันเพิ่งพบปัญหานี้เช่นกัน ฉันมีตารางขนาดใหญ่มากในไดอะล็อก div มันคือ> 15,000 แถว เมื่อเรียก. ว่าง () บนไดอะล็อก div ฉันได้รับข้อผิดพลาดด้านบน

ฉันพบวิธีแก้ปัญหาแบบกลมซึ่งก่อนที่ฉันจะเรียกการทำความสะอาดกล่องโต้ตอบฉันจะลบแถวอื่น ๆ ทั้งหมดออกจากตารางที่มีขนาดใหญ่มากจากนั้นเรียก. empty () ดูเหมือนว่าจะได้ผล ดูเหมือนว่า JQuery เวอร์ชันเก่าของฉันไม่สามารถจัดการกับองค์ประกอบขนาดใหญ่เช่นนี้ได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.