web-dev-qa-db-ja.com

ChromeおよびIE

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

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

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

Firefoxでは上下にスクロールでき、上記の固定/固定解除はごくわずかです–シルクのように滑らかです。

ChromeまたはIEでスクロールしようとすると、スクロールイベントが遅れるように見え、ブロックの「グリッチ」が1秒間表示されます。コードの遅れではなく、何かのようです。ブラウザで。

これを修正する方法はありますか?私は私のウィットの終わりにいます。

同じ効果を別の方法で実現する方法についての提案に感謝します...

27
Marcelo Mason

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

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

JavaScriptでハードコーディングする代わりに、クラスを切り替えて状態(静的位置と固定位置)を切り替えることもお勧めします。次に、問題を明確に分離します 誤って余分な再描画の可能性を避けます (「ブラウザは賢い」セクションを参照)。 ( jsfiddleの例

x msの一時停止を待ちます

// 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 ms待ちます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を使用しているので、シンプルで jQuery Waypoints プラグインを見てみましょう。あなたの問題へのエレガントなソリューション。ユーザーが特定のウェイポイントにスクロールしたときにコールバックを定義するだけです。

例:( 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
    });
});
44
gregers

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

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

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

1
Rafael Verger