最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - synchronise scrolling between 2 divs in native javascript (2020) - Stack Overflow

programmeradmin7浏览0评论

I'm trying to make a fake/duplicated scroll element that is synced with the actual x-scroll of a div in native javaScript. The use case for me is on a long table to have the x-scroll be present on screen when you're not at the bottom of the table.

This solves the situation of having a really wide table with a min-width that exceeds the current page/view-port width, causing the table to side/x-scroll. However, if the table is very long, the scroll can only be set on top or bottom of the table. That means if people are mid-way down the table and want to scroll across to see all of the columns, they would have difficulty in doing it there.

See image:

Yep, it's been done to death IN JQUERY. According to my research, no one on SO knows or has been interested in doing this in native javaScript (esp 2020). My version for reference is also in jQuery, it needs to be converted.

  $dupScroll.scroll(function () {
    if (scrolling) {
      scrolling = false;
      return true;
    }
    scrolling = true;
    $tableParent.scrollLeft($dupScroll.scrollLeft());
  });
  $tableParent.scroll(function () {
    if (scrolling) {
      scrolling = false;
      return true;
    }
    scrolling = true;
    $dupScroll.scrollLeft($tableParent.scrollLeft());
  });

All the jQuery solutions:

  1. How to Scroll two div's at the same time?
  2. synchronizing scrolling between 2 divs
  3. synchronizing scrolling between 2 divs with different text size
  4. How to sync the scroll of two divs by ID
  5. synchronise scrolling of two divs

Help is appreciated and will be useful for all the people needing to do the same post-jQuery. I'm currently working on this myself but running into snags here and there, the 1st being attaching a scroll event onto an element. If I make something that works, I'll post it here. Thanks.

I'm trying to make a fake/duplicated scroll element that is synced with the actual x-scroll of a div in native javaScript. The use case for me is on a long table to have the x-scroll be present on screen when you're not at the bottom of the table.

This solves the situation of having a really wide table with a min-width that exceeds the current page/view-port width, causing the table to side/x-scroll. However, if the table is very long, the scroll can only be set on top or bottom of the table. That means if people are mid-way down the table and want to scroll across to see all of the columns, they would have difficulty in doing it there.

See image:

Yep, it's been done to death IN JQUERY. According to my research, no one on SO knows or has been interested in doing this in native javaScript (esp 2020). My version for reference is also in jQuery, it needs to be converted.

  $dupScroll.scroll(function () {
    if (scrolling) {
      scrolling = false;
      return true;
    }
    scrolling = true;
    $tableParent.scrollLeft($dupScroll.scrollLeft());
  });
  $tableParent.scroll(function () {
    if (scrolling) {
      scrolling = false;
      return true;
    }
    scrolling = true;
    $dupScroll.scrollLeft($tableParent.scrollLeft());
  });

All the jQuery solutions:

  1. How to Scroll two div's at the same time?
  2. synchronizing scrolling between 2 divs
  3. synchronizing scrolling between 2 divs with different text size
  4. How to sync the scroll of two divs by ID
  5. synchronise scrolling of two divs

Help is appreciated and will be useful for all the people needing to do the same post-jQuery. I'm currently working on this myself but running into snags here and there, the 1st being attaching a scroll event onto an element. If I make something that works, I'll post it here. Thanks.

Share Improve this question edited Dec 3, 2020 at 0:13 bot19 asked Dec 2, 2020 at 23:35 bot19bot19 81410 silver badges19 bronze badges 8
  • 1 In CSS, something like #container{ overflow:scroll; } shows the scrollbars. Your question is actually very unclear. Synchronized as in percentage being the same? Do the math. – StackSlave Commented Dec 2, 2020 at 23:47
  • 2 div1.addEventListener( 'scroll', e => div2.scrollTop = div1.scrollTop) should do the trick. Keep in mind that JS does not trigger a scroll event on the second element as its progrmatically set, so there's no need for a flag to see which is being scrolled. – somethinghere Commented Dec 2, 2020 at 23:55
  • 1 @bot19 Check my answer below, you can just replace any instance of scrollTop with scrollLeft (and scrollHeight with scrollWidth, clientHeight with clientWidth for the second bit of my answer) – somethinghere Commented Dec 3, 2020 at 0:22
  • 1 @bot19 Actually, I have edited my answer to include both directions being synchronised. Hope that helps! – somethinghere Commented Dec 3, 2020 at 0:26
  • 1 @bot19 Do you still need that or is both directions also okay? I find it simple enough to understand either way, with height and top being pretty clear as to how it works. – somethinghere Commented Dec 3, 2020 at 0:28
 |  Show 3 more ments

1 Answer 1

Reset to default 8

Here's the simple way to keep two divs aligned. Javascript doesn't dispatch event on actions from scripts by default, so there's no need to keep track of which div is being scrolled.

const divs = document.querySelectorAll( 'div' );

divs.forEach(div => div.addEventListener( 'scroll', e => {
  
  divs.forEach(d => {
  
    d.scrollTop = div.scrollTop;
    d.scrollLeft = div.scrollLeft;
  
  });
  
}) );
html, body {

  height: 100%;
  
}
body {

  display: flex;
  padding: 0;
  margin: 0;

}
div {

  width: 50%;
  height: 100%;
  overflow: scroll;

}
span {

  width: 200vw;
  height: 300vh;
  display: block;
  background: linear-gradient(90deg, transparent, yellow), linear-gradient( 0deg, red, blue, green );
  
}
#div2 {

  margin-top: 30px;
  
}
<div id="div1"><span></span></div>
<div id="div2"><span></span></div>

With Relative Scroll in Different Sized Containers

If you want to acplish this with differently sized containers and relative scroll, just normalize the scroll value and multiply it again:

const divs = document.querySelectorAll( 'div' );

divs.forEach(div => div.addEventListener( 'scroll', e => {
  
  const offsetTop = div.scrollTop / (div.scrollHeight - div.clientHeight);
  
  const offsetLeft = div.scrollLeft / (div.scrollWidth - div.clientWidth);
  
  divs.forEach(d => {
  
    d.scrollTop = offsetTop * (d.scrollHeight - d.clientHeight);
    d.scrollLeft = offsetLeft * (d.scrollWidth - d.clientWidth);
    
  });
  
}) );
html, body {

  height: 100%;
  
}
body {

  display: flex;
  padding: 0;
  margin: 0;

}
div {

  width: 50%;
  height: 100%;
  overflow: scroll;

}
span {

  width: 200vw;
  height: 300vh;
  display: block;
  background: linear-gradient(90deg, transparent, yellow), linear-gradient( 0deg, red, blue, green );
  
}
#div2 span {
  
  height: 500vh;
  width: 500vw;
  
}
<div id="div1"><span></span></div>
<div id="div2"><span></span></div>

发布评论

评论列表(0)

  1. 暂无评论