28

ユーザーがページを下にスクロールしても、コンテンツ ブロックが常にユーザーに表示されるようにしようとしています。また、コンテンツ ブロックを上下にスクロールできる必要があります。これは、私が何を意味するかを示すために、簡素化されたバージョンのフィドルです。

http://jsfiddle.net/9efV/2/

下にスクロールすると、赤いブロックの一番下に到達するまで、ブロックがウィンドウに固定され、上にスクロールすると元に戻ります。

Firefox では、上下にスクロールすることができ、上記の修正/修正解除は知覚できません。シルクのようにスムーズです。

ただし、Chrome または IE でスクロールしようとすると、スクロール イベントが遅れているように見え、ブロックが 1 秒間「グリッチ」するのを見ることができます。これはコードの遅れではなく、ブラウザに問題があるようです。

これを修正する方法はありますか?私は機知に富んでいます。

同じ効果を別の方法で実現する方法についての提案をいただければ幸いです...ありがとう

4

2 に答える 2

47

JavaScriptはUIと同じスレッドで実行されるため、スクロールイベントコールバックはUIスレッドをブロックし、ラグを引き起こす可能性があります。一部のブラウザは多くのイベントリスナーを起動するため、スクロールイベントリスナーを調整する必要があります。特に、アナログスクロールデバイスを搭載したOSXを使用している場合。リスナーで多くの高さ計算を行うため、発生するすべてのスクロールイベントに対してリフロー(非常に高価)がトリガーされます。

リスナーを絞るには、リスナーが毎回発火しないようにする必要があります。通常、ブラウザがxミリ秒の間イベントをトリガーしなくなるまで待つか、コールバックを呼び出すまでの間に最小の時間があります。値を調整して効果を確認してください。ブラウザに時間がかかるまで(通常は5〜40ミリ秒)コールバックの実行が遅れるため、0ミリ秒でも役立ちます。

また、JavaScriptでハードコーディングするのではなく、クラスを切り替えて状態(静的位置と固定位置)を切り替えることもお勧めします。そうすれば、関心の分離がより明確になり、誤って余分に再描画される可能性を回避できます(「ブラウザは賢い」セクションを参照)。(jsfiddleの例

xミリ秒の一時停止を待ちます

// return a throttled function
function waitForPause(ms, callback) {
    var timer;

    return function() {
        var self = this, args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function() {
            callback.apply(self, args);
        }, ms);
    };
}

this.start = function() {
    // wrap around your callback
    $window.scroll( waitForPause( 30, self.worker ) );
};

少なくともxミリ秒待つjsfiddle

function throttle(ms, callback) {
    var timer, lastCall=0;

    return function() {
        var now = new Date().getTime(),
            diff = now - lastCall;
        console.log(diff, now, lastCall);
        if (diff >= ms) {
            console.log("Call callback!");
            lastCall = now;
            callback.apply(this, arguments);
        }
    };
}

this.start = function() {
    // wrap around your callback
    $window.scroll(throttle(30, self.worker));
};

jQuery Waypoints すでにjQueryを使用しているので、問題に対するシンプルでエレガントなソリューションを備えたjQueryWaypointsプラグインを見てみましょう。ユーザーが特定のウェイポイントまでスクロールしたときのコールバックを定義するだけです。

例:(jsfiddle

$(document).ready(function() {
    // throttling is built in, just define ms
    $.waypoints.settings.scrollThrottle = 30;

    $('#content').waypoint(function(event, direction) {
        $(this).toggleClass('sticky', direction === "down");
        event.stopPropagation();
    }, {
        offset: 'bottom-in-view' // checkpoint at bottom of #content
    });
});
于 2012-06-14T18:47:20.193 に答える
1

スクロールバー用のjqueryプラグインを試したり、アニメーションを使用して上下にスクロールしたりしましたか? すべてのブラウザが同じように動作するように強制します (または十分に閉じます)。

何が起こるかというと、Firefox (少なくとも v12) には「ネイティブ」なスクロール アニメーションがあります。任意の URL に移動すると、スクロール アクションの滑らかさに気付くことができますが、これは Chrome や IE などの他のブラウザーには実装されていません。

jquery スクローラー プラグインの例:

于 2012-06-12T16:23:32.143 に答える