2012-09-14 3 views
5

私は、ユーザーが一定の距離を上からスクロールした後にピックアップする固定メニューのページに取り組んでいます。ページを下にスクロールすると、メニューからの別のリンクが与えられます色を変更するクラスこれはChromeとSafariでうまくいくようですが、Firefoxではページが一番上にフリーズします。私はそれがいくつかのコードを絶え間なくループしているのか疑問に思っています...本質的にウィンドウをフリーズしています。window.scroll function freezes firefox

ここに私のコードです。

$.localScroll({ 
    onBefore: function() { 
     $('body').data('scroll-executing', true); 

    }, 
    onAfter: function() { 
     $('body').data('scroll-executing', false); 
     $(window).trigger("scroll"); 
    } 
}); 

$(window).scroll(function() { 
    if ($(this).scrollTop() > 259) { 
     $('.nav').addClass("f-nav"); 
    } else { 
     $('.nav').removeClass("f-nav"); 
    } 
}); 

$(window).scroll(function() { 
    if ($('body').data('scroll-executing')) { 
     return; 
    } 
    // find the a with class 'active' and remove it 
    $("a").removeClass('active'); 
    // get the amount the window has scrolled 
    var scroll = $(window).scrollTop(); 
    // add the 'active' class to the correct #nav based on the scroll amount 

    if (scroll > 2150) { 
     $("#nav_3").removeClass('active'); 
     $("#nav_5").attr('class', 'active'); 
     setHash("contact"); 

    } else if (scroll > 1300) { 
     $("#nav_2").removeClass('active'); 
     $("#nav_3").attr('class', 'active'); 
     setHash("portfolio"); 

    } else if (scroll > 400) { 
     $("#nav_2").attr('class', 'active'); 
     setHash("about"); 

    } else if (scroll <= 380) { //when I remove this section, the problem goes away. 
     $("#nav_1").attr('class', 'active'); 
     setHash("home"); 
    } 

}); 

setHash定義を追加するのを忘れました。ここにあります。

また、CPUが100%まで上がっていることに気付きましたが、その理由を理解できないようです。

問題は、else if(scroll < = 380)で始まるコードの3番目のセクションにあります。私は排除のプロセスによってそれを考え出した。誰もそれがループしたり、決して終わらない何かをしているのを見ることができますか?または、なぜFirefoxがページの上部でフリーズするのか説明しますか?

私はこれの新しさです...私はここ数日でjqueryをピックアップしました。基本的には、私が必要とするものに適合するようにたくさんのグーグルとコードを適合させています。

ご協力いただければ幸いです。

+0

jsfiddle.netなどの問題を示すサンプルページへのリンクを付けることはできますか? –

答えて

3

スクロールイベントに多すぎるコードを実行すると、スクロールごとにスクロールイベントが100回トリガされるので、throttleまたはdebounceのようなメソッドを持つライブラリを使用することを検討できます。

http://documentcloud.github.com/underscore/#throttle

これは、ウィンドウのスクロールイベントにハンドラをアタッチすることは非常に、非常に悪い考えです。ブラウザによっては、スクロールイベントが多発し、スクロールコールバックにコードを置くと、ページをスクロールする試みが遅くなります(良い考えではありません)。結果としてスクロール・ハンドラのパフォーマンス低下は、全体的なスクロールのパフォーマンスを合成するだけです。その代わりに、何らかの形のタイマーを使用してXミリ秒ごとにORをチェックしてスクロールイベントをアタッチし、遅延の後に(または指定された回数の実行後に、さらには遅れて)コードを実行してください。 http://ejohn.org/blog/learning-from-twitter/

+0

間隔は素晴らしい考えでした。また、setHashはウィンドウではなくボディを選択していましたが、これもいくつかの問題を引き起こしていました。今私はそれが働いている。それは、いくつかのものをクリーンアップし、変数をキャッシングする時間です。ご協力いただきありがとうございます。 – Daniel

1

基本的には、スクロールイベントで実行しすぎています。 @undefinedが言っているように、ブラウザはあなたが思っている以上にこれを多く呼びます。いくつかのヒント:

何度も呼び出される関数の中にjQueryオブジェクトを作成しておきます。そうすることで、関数が呼び出されるたびに、同じjQueryオブジェクトが再作成されることはありません。

var nav2 = $("#nav_2"); 
$(window).scroll(function() { 
    ... 
    nav2.removeClass('active'); 
    ... 
}); 

何度も何度も呼び出されるとするときも同様に、クラスを追加し、削除すると、あなたの処理サイクルを大量に消費することができます - あなたは$('.nav').addClass("f-nav");のように、要素のクラス全体にアクセスしている場合は特に。

代わりに、クラスが存在しない場合にのみ追加/削除してください。ような何か:

var alreadyAdded = false; 
var alreadyRemoved = false; 
$(window).scroll(function() { 
    if ($(this).scrollTop() > 259) { 
     if(!alreadyAdded){ 
     $('.nav').addClass("f-nav"); 
     alreadyAdded = true; 
     alreadyRemoved = false; 
     } 
    } else if(!alreadyRemoved) { 
     $('.nav').removeClass("f-nav"); 
     alreadyAdded = false; 
     alreadyRemoved = true; 
    } 
}); 

、それはおそらくまだスクロールイベントに接続されたすべてのコードでゆっくりとスクロールすると述べているすべて。たぶん同じ効果を得る別の方法があります。 Firefoxがフリーズしている場合、私はIEでどのくらい遅くなければならないのか想像するだけです。

0

その他の問題に加えて、$('body').scrollTop()はFirefoxで常に0を返します。 setHash()$('html,body').scrollTop(scrollmem);}になると、画面の上部にジャンプします。これは、ユーザーが最初にページを読み込んだときに画面の上部に詰まったように見えます。 $(window).scrollTop()は、スロットリングとともに、この問題を解決します。