「chromeuncaught rangeerror maximum call stack size exceeded」
このエラーの回避策について行った事です。
メッセージの意味
本来の意味は call stack とある通り、再帰呼び出し等で戻り先アドレスを保持するスタック領域のオーバーフローなのですが。
再帰処理など組み込んでいない!と思っていても、jQuery内部でもそうなっていないとは限りません。
中の作りは知りませんが(知りたくもないですが)、要素へのイベントバインドではそんなことを行っているのでしょうね。
参考になったサイトと解決策
さて、ググってみても、よくあるのは「再帰しすぎじゃない?」という投げやりな回答だけ。。
諦めずに調べると、 stack overflow にこんなものが!
$('td').click(function () {
if ($(this).context.id != null && $(this).context.id != '') {
foo($('#docId').val(), $(this).attr('id'));
}
return false;
});
数万以上の td があるそうで、そこで発生したそうです。
再帰なんて行っていないですよね。
で、それに対する素晴らしい回答がこちら。
$('body').on('click', 'td', function(){
...
});
bindする要素の数を減らしているわけですね。
(この場合、数万以上ある td に対してではなく、通常1つしかない body に対して bindしています)
body をクリックしたときに、その中にある要素が指定されたもの(td)であれば、コールバック関数が呼び出されるというものです。
素晴らしい!
これで見事解決しました。
jQuery.lazyLoadプラグインを使った場合
しかし、まだ完全な解決には至りませんでした。
今回私が作ったサイト(管理画面系)では、大量の画像(数万以上)を表示させる、という命題がありまして。
画面ロード時に一度にロードさせるとページ後半で必ず not found となる画像が大量発生します。
そのためlazyLoad を使ったのですが。
この中で全画像に対しloadイベントをバインドさせていたために同様の問題が発生してしまいました。
まあ、結論から言うと、 jQuery.lazyLoad を勝手に書き換えてしまったわけですが(^-^;
改造したのは良いのですが、勝手に公開するのはいかがなものかと思いまして(それにあまり自信が無い・・)。
という事でヒントだけ。
・img 要素に対する lazyLoad のアサインではなく、imgを含む要素に対し lazyLoad をアサインさせる。
・lazyLoadプラグイン中の
$("<img />").one("load", function() {
・・・
})
を
$self.find('img').each( function(){
$(this).one("load", function() {
・・・
})
})
としたわけです。
※$(this)を使ってよいかどうか自信がないですが・・
参考になれば幸いです。