26

DIV次のコードを使用して、2 つの同期スクロールを実装しようとしています。

デモ

$(document).ready(function() {
    $("#div1").scroll(function () { 
        $("#div2").scrollTop($("#div1").scrollTop());
    });
    $("#div2").scroll(function () { 
        $("#div1").scrollTop($("#div2").scrollTop());
    });
});

#div1まったく同じ内容ですが、#div2サイズが異なります。たとえば、

#div1 {
 height : 800px;
 width: 600px;
}
#div1 {
 height : 400px;
 width: 200px;
}

このコードでは、2 つの問題に直面しています。

1) div のサイズが異なるため、スクロールがうまく同期されていません。これは、scrollTop値を直接設定しているためです。スクロールされたコンテンツのパーセンテージを見つけて、対応するscrollTop値を計算する必要がありますdiv。実際の高さと現在のスクロール位置を見つける方法がわかりません。

2) この問題は にのみ見られfirefoxます。Firefox では、他のブラウザーのようにスクロールがスムーズではありません。これは、上記のコードがスクロール イベントの無限ループを作成しているためだと思います。なぜこれがFirefoxでのみ起こっているのか、私にはわかりません。この問題を解決できるように、スクロール イベントのソースを見つける方法はありますか。

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

4

8 に答える 8

49

を使用element.scrollTop / (element.scrollHeight - element.offsetHeight)してパーセンテージを取得できます ( ~ の間の値に0なります1)。(.scrollHeight - .offsetHeight)したがって、比例スクロールのために、他の要素にこの値を掛けることができます。

ループ内でリスナーがトリガーされるのを避けるには、一時的にリスナーのバインドを解除し、 を設定してscrollTop再度バインドします。

var $divs = $('#div1, #div2');
var sync = function(e){
    var $other = $divs.not(this).off('scroll'), other = $other.get(0);
    var percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);
    other.scrollTop = percentage * (other.scrollHeight - other.offsetHeight);
    // Firefox workaround. Rebinding without delay isn't enough.
    setTimeout( function(){ $other.on('scroll', sync ); },10);
}
$divs.on( 'scroll', sync);

http://jsfiddle.net/b75KZ/5/

于 2013-09-23T06:54:26.200 に答える
4

Runs like clockwork (see DEMO)

$(document).ready(function(){

  var master = "div1"; // this is id div
  var slave = "div2"; // this is other id div
  var master_tmp;
  var slave_tmp;
  var timer;

  var sync = function ()
  {
    if($(this).attr('id') == slave)
    {
      master_tmp = master;
      slave_tmp = slave;
      master = slave;
      slave = master_tmp;
    }

    $("#" + slave).unbind("scroll");

    var percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);

    var x = percentage * ($("#" + slave).get(0).scrollHeight - $("#" + slave).get(0).offsetHeight);

    $("#" + slave).scrollTop(x);

    if(typeof(timer) !== 'undefind')
      clearTimeout(timer);

    timer = setTimeout(function(){ $("#" + slave).scroll(sync) }, 200)
  }

  $('#' + master + ', #' + slave).scroll(sync);

});
于 2015-01-13T05:21:13.780 に答える
2

div のサイズが等しい場合、以下のコードはそれらを同期的にスクロールする簡単な方法です。

scroll_all_blocks: function(e) {
        var scrollLeft = $(e.target)[0].scrollLeft;

        var len = $('.scroll_class').length;
        for (var i = 0; i < len; i++)
        {
            $('.scroll_class')[i].scrollLeft = scrollLeft;
        }

    }

ここでは水平スクロールを使用していますが、代わりにここで scrollTop を使用できます。この関数はscrolldiv のイベントで呼び出されるためe、イベント オブジェクトにアクセスできます。第二に、この行に適用するために計算された div の対応するサイズの比率を単純に持つことができます$('.scroll_class')[i].scrollLeft = scrollLeft;

于 2013-10-01T11:38:10.743 に答える
1

私は Pawel のクリーンなソリューションが好きですが、必要なものが欠けており、スクロールし続けるという奇妙なスクロール バグがあり、私のプラグインは 2 つだけでなく複数のコンテナーで動作します。

http://www.xtf.dk/2015/12/jquery-plugin-synchronize-scroll.html

例とデモ: http://trunk.xtf.dk/Project/ScrollSync/

プラグイン: http://trunk.xtf.dk/Project/ScrollSync/jquery.scrollSync.js

$('.scrollable').scrollSync();

于 2015-12-01T10:17:17.313 に答える
1

比例スクロールではなく、各フィールドで同じ量のピクセルをスクロールしたい場合は、スクロールイベントをバインドしているフィールドの現在の値に変更の値を追加できます。

#leftそれが小さなフィールドであり、より大きなフィールドであるとしましょう#right

var oldRst = 0;

$('#right').on('scroll', function () {
    l = $('#left');
    var lst = l.scrollTop();
    var rst = $(this).scrollTop();

    l.scrollTop(lst+(rst-oldRst)); // <-- like this

    oldRst = rst;
});

https://jsfiddle.net/vuvgc0a8/1/

#rightchange の値を'sに等しく設定するだけでなく、その値を追加することで、大きなフィールドより小さいにもscrollTop()かかわらず、小さなフィールドを上下にスクロールできます。scrollTop()この例は、Facebook のユーザー ページです。

これは私がここに来たときに必要だったので、共有したいと思いました.

于 2016-04-12T22:11:20.013 に答える
0

Pawelソリューションから(最初の回答)。

jQueryを使用した水平同期スクロールの場合、これが解決策です:

var $divs = $('#div1, #div2'); //only 2 divs
var sync = function(e){
    var $other = $divs.not(this).off('scroll');
    var other = $other.get(0);
    var percentage = this.scrollLeft / (this.scrollWidth - this.offsetWidth);
    other.scrollLeft = percentage * (other.scrollWidth - other.offsetWidth);
    setTimeout( function(){ $other.on('scroll', sync ); },10);
}

$divs.on('scroll', sync);

JSFiddle

複数の水平方向に同期された div の別の解決策はこれですが、同じ幅の div で機能します。

var $divs = $('#div1, #div2, #div3'); //multiple divs
var sync = function (e) {
    var me = $(this);
    var $other = $divs.not(me).off('scroll');
    $divs.not(me).each(function (index) {
        $(this).scrollLeft(me.scrollLeft());
    });
    setTimeout(function () {
        $other.on('scroll', sync);
    }, 10);
}
$divs.on('scroll', sync);

注意: 同じ幅の div のみ

JSFiddle

于 2015-07-08T16:57:05.160 に答える