5

ユーザーが上から一定の距離をスクロールした後にピックアップする固定メニューのあるページで作業しています。ページを下にスクロールすると、メニューからのさまざまなリンクに色を変更するクラスが与えられます。これらはすべて Chrome と Safari ではうまく機能しているように見えますが、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 定義を追加するのを忘れていました。ここにあります。

setHash = function(hash) {
    var scrollmem = $('body').scrollTop();
    window.location.hash = hash;
    $('html,body').scrollTop(scrollmem);
}

また、CPU が 100% まで上昇していることにも気付きましたが、その理由がわかりません。

問題は、else if (scroll <= 380) で始まるコードの 3 番目のセクションにあります。消去法でわかりました。誰かがそれがループしている、または決して終わらない何かをしているのを見ることができますか...またはFirefoxがページの上部でフリーズする理由を説明できますか?

私はこれらすべてに慣れていません...ここ数日でjqueryを手に入れたばかりで、基本的に多くのグーグル検索を行い、必要なものに適合するようにコードを調整しています。

どんな助けでも大歓迎です。

4

3 に答える 3

3

スクロール イベントであまりにも多くのコードを実行するのはやり過ぎです。各スクロールで、ブラウザーはスクロール イベントを 100 回トリガーします。throttleまたはのようなメソッドを持つライブラリの使用を検討できますdebounce

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

ウィンドウのスクロール イベントにハンドラーを追加するのは、非常に悪い考えです。ブラウザーによっては、スクロール イベントが頻繁に発生する可能性があり、コードをスクロール コールバックに配置すると、ページをスクロールしようとすると速度が低下します (お勧めできません)。その結果、スクロール ハンドラのパフォーマンスが低下すると、全体的なスクロールのパフォーマンスが悪化するだけです。代わりに、なんらかの形式のタイマーを使用して X ミリ秒ごとにチェックするか、スクロール イベントをアタッチして、遅延後 (または指定された回数の実行後、さらに遅延後) にのみコードを実行する方がはるかに優れています。 http://ejohn.org/blog/learning-from-twitter/

于 2012-09-14T17:07:31.237 に答える
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 でどれだけ遅いか想像することしかできません。

于 2012-09-14T17:24:34.330 に答える
0

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

于 2012-09-14T21:19:49.460 に答える