如何同步两个div的滚动位置?

Jos*_* U. 58 javascript jquery

我希望有2个div大小到特定宽度(即500px).一个在另一个之上水平对齐.

顶部框应隐藏其滚动条,底部应显示滚动条,当用户滚动时,我希望顶部框的偏移更改为底部框的值.因此,当底部DIV水平滚动时,顶部DIV也会同时滚动.

如果它让这个过程更容易,我很高兴在Jquery中这样做.

Jas*_*per 91

$('#bottom').on('scroll', function () {
    $('#top').scrollTop($(this).scrollTop());
});
Run Code Online (Sandbox Code Playgroud)

这里我们正在使用.scrollTop()它的所有scrollTop值,从带有滚动条的元素获取值,并设置scrollTop另一个元素以同步它们的滚动位置:http://api.jquery.com/scrollTop

这假设您的bottom元素的ID为,bottom并且您的top元素的ID为top.

您可以top使用CSS 隐藏元素的滚动条:

#top {
    overflow : hidden;
}
Run Code Online (Sandbox Code Playgroud)

这是一个演示:http://jsfiddle.net/sgcer/1884/

我想我从来没有真正有理由这样做,但它看起来很酷.

  • @JosephU.这是一个更新的JSFiddle,演示使用`scrollLeft`而不是`scrollTop`:http://jsfiddle.net/sgcer/1/ (3认同)

Art*_*kyi 51

我知道这是一个旧线程,但也许这会帮助某人.如果你需要在双向上同步滚动,那么仅处理两个容器的滚动事件并设置滚动值是不够的,因为滚动事件进入循环并且滚动不平滑(尝试垂直滚动鼠标轮是Hightom给出的一个例子.

以下是如何检查是否已在同步滚动的示例:

var isSyncingLeftScroll = false;
var isSyncingRightScroll = false;
var leftDiv = document.getElementById('left');
var rightDiv = document.getElementById('right');

leftDiv.onscroll = function() {
  if (!isSyncingLeftScroll) {
    isSyncingRightScroll = true;
    rightDiv.scrollTop = this.scrollTop;
  }
  isSyncingLeftScroll = false;
}

rightDiv.onscroll = function() {
  if (!isSyncingRightScroll) {
    isSyncingLeftScroll = true;
    leftDiv.scrollTop = this.scrollTop;
  }
  isSyncingRightScroll = false;
}
Run Code Online (Sandbox Code Playgroud)
.container {
  width: 200px;
  height: 500px;
  overflow-y: auto;
}

.leftContainer {
  float: left;
}

.rightContainer {
  float: right;
}
Run Code Online (Sandbox Code Playgroud)
<div id="left" class="container leftContainer">
Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, quia dolor sit, amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur? At vero eos et accusamus et iusto odio dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id, quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet, ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
</div>
<div id="right" class="container rightContainer">
Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, quia dolor sit, amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur? At vero eos et accusamus et iusto odio dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id, quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet, ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
</div>
Run Code Online (Sandbox Code Playgroud)

这是小提琴.

  • 完美......工作棒极了!谢谢. (3认同)
  • 一个纯 javascript 解决方案。谢谢你。 (3认同)

Hig*_*tom 11

我一直在寻找双向解决方案,谢谢大家,你的建议让我这样做:

$('#cells').on('scroll', function () {
$('#hours').scrollTop($(this).scrollTop());
$('#days').scrollLeft($(this).scrollLeft());});
Run Code Online (Sandbox Code Playgroud)

请参阅JSFiddle:https://jsfiddle.net/sgcer/1274/

希望有一天能帮到某人:-)


Rob*_*aws 5

好的,所以我评估了这里提供的所有选项,它们都有一种或另一种形式的限制:

  • 接受的答案使用鼠标滚轮已知问题的困扰。
  • 接下来的最高给予好评没有滚轮的问题,但只适用于已知元素为两个。如果您需要更多元素,则它不可扩展。
  • 唯一显示出承诺的解决方案是Lacho 的,但代码中存在未包含在代码段中的已知元素引用。从好的方面来说,它具有性能所需的结构,并且是在 TypeScript 中。

我利用它创建了一个可重用的版本,它可以处理无限数量的元素,并且不需要 JQuery。

function scrollSync(selector) {
  let active = null;
  document.querySelectorAll(selector).forEach(function(element) {
    element.addEventListener("mouseenter", function(e) {
      active = e.target;
    });

    element.addEventListener("scroll", function(e) {
      if (e.target !== active) return;

      document.querySelectorAll(selector).forEach(function(target) {
        if (active === target) return;

        target.scrollTop = active.scrollTop;
        target.scrollLeft = active.scrollLeft;
      });
    });
  });
}

//RWM: Call the function on the elements you need synced.
scrollSync(".scrollSync");
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看 JSFiddle:http : //jsfiddle.net/gLa2ndur/3。您可以看到它同时使用了水平和垂直滚动示例。

唯一已知的限制是它可能不适用于不同大小的 div。如果您的用例认为有必要(我的没有),我相信有人可以将安德鲁的工作纳入其中。

我希望这对某人有帮助!