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. При использовании тела или таблицы я не получаю достаточно событий.
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». Думаю, вам будет интересна эта статья о привязке событий и делегировании


Или вы можете просто использовать метод jQuery " .on () " с тем же эффектом:

$('body').on('click', 'td', function(){
        ...
});
vantrung -cuncon
источник
спасибо, мы все равно боремся за производительность, так что это отличная идея :-)
Энди
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 01
7

Моя была скорее ошибкой, то, что произошло, было щелчком цикла (я думаю) в основном при нажатии на логин, который также был нажат родительским, что в конечном итоге привело к превышению максимального размера стека вызовов.

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

<li class="clickhere">
  <a href="#" class="login">login</a>
</li>
Jsonras
источник
3

Эта проблема возникла у меня, когда я использовал jQUery Fancybox на веб-сайте со многими другими плагинами jQuery. Когда я использовал LightBox ( сайт здесь ) вместо Fancybox, проблема исчезла.

Сильвио Дельгадо
источник
1

Вы можете использовать

  $(document).on('click','p.class',function(e){
   e.preventDefault();
      //Code 
   });
demenvil
источник
0

Недавно я тоже столкнулся с этой проблемой. У меня была очень большая таблица в диалоге div. Было> ​​15 000 строк. Когда .empty () был вызван в div диалога, я получал ошибку, указанную выше.

Я нашел обходное решение, в котором, прежде чем я вызываю очистку диалогового окна, я удаляю все остальные строки из очень большой таблицы, а затем вызываю .empty (). Хотя, похоже, это сработало. Похоже, моя старая версия JQuery не может обрабатывать такие большие элементы.

dev4life
источник