Home > database >  How do I synchronise scrolling of two different sized boxes using one as a reference using JavaScrip
How do I synchronise scrolling of two different sized boxes using one as a reference using JavaScrip

Time:12-03

I have two boxes, one is smaller then the other. The small box contains the same text as the other, but since it's smaller auto scrolling takes a longer time. I would like the big box to end scrolling the same time the small box ends.

let stepSize = 0.5;
let masterSpeed = 50;
let masterElement = document.getElementById("master-box");
let slaveElement = document.getElementById("slave-box");

var scroll = 0;

window.setInterval(function(){ 
  if(masterElement.scrollTop > scroll)
  scroll = masterElement.scrollTop;
  masterElement.scrollTo({ top: scroll, behavior: 'smooth' })
  scroll  = 1; 
}, masterSpeed); //THIS WILL RUN IN EVERY 50 MILISECONDS

// Match slave speed to master speed
let masterDistance = masterElement.scrollHeight - masterElement.clientHeight;
let masterScrollTime = masterDistance / masterSpeed;
let syncedSpeed = masterDistance / masterScrollTime;

window.setInterval(function(){ 
  if(slaveElement.scrollTop > scroll)
  scroll = slaveElement.scrollTop;
  slaveElement.scrollTo({ top: scroll, behavior: 'smooth' })
  scroll  = 1; 
}, syncedSpeed); //THIS WILL RUN IN EVERY 50 MILISECONDS
.container {
  display: flex;
}
span {
  display: block;
  height : 3px;
  background: red;
}
.box1{
  width: 100px;
  height: 200px;
  overflow-y: auto;
  border: 2px solid blue;
  margin: 10px;
}
.box2{
  width: 200px;
  height: 300px;
  overflow-y: auto;
  border: 2px solid blue;
  margin: 10px;
}
<div class="container">
<div class="box1" id="master-box">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!<span></span></div>
<div class="box2" id="slave-box">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!<span></span></div>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Use percentages rather than the scroll index. Make a couple of helper functions and it'll be much easier to understand. Behold:

let masterElement = document.getElementById("master-box");
let slaveElement = document.getElementById("slave-box");

// Scroll to a percentage of the vertical height
function scrollToPct(element, pct){
  var scroll = (element.scrollHeight - element.clientHeight) / 100 * pct;
  element.scrollTo({ top: scroll, behavior: 'smooth' });
}

// Get the percentage of vertical scroll
function getScrollPct(element){
  return element.scrollTop / (element.scrollHeight - element.clientHeight) * 100;
}

// Listen to the mastre element and update the slave element accordingly
masterElement.addEventListener('scroll', function(){
  var scroll_pct = getScrollPct(this);
  scrollToPct(slaveElement, scroll_pct);
});

// turn on the autoscroll
setInterval(function(){
  var scroll_pct = getScrollPct(masterElement);
  scrollToPct(masterElement, scroll_pct   5);
}, 10);
.container {
  display: flex;
}
span {
  display: block;
  height : 3px;
  background: red;
}
.box1{
  width: 100px;
  height: 200px;
  overflow-y: auto;
  border: 2px solid blue;
  margin: 10px;
}
.box2{
  width: 200px;
  height: 300px;
  overflow-y: auto;
  border: 2px solid blue;
  margin: 10px;
}
<div class="container">
<div class="box1" id="master-box">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!<span></span></div>
<div class="box2" id="slave-box">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!<span></span></div>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Do not use setInterval twice. Instead, update the second one using a percentage of scroll instead of just using the same scrollTop.

Also, setting the behavior to smooth was causing animations to run which could interfere with your scrolling commands.

Lastly, you need to take the scrollHeight and clientHeight into account.

const masterSpeed = 50;
const stepSize = 10;
const masterElement = document.getElementById("master-box");
const slaveElement = document.getElementById("slave-box");

const masterScrollHeight = masterElement.scrollHeight;
const slaveScrollHeight = slaveElement.scrollHeight;
const masterClientHeight = masterElement.clientHeight;
const slaveClientHeight = slaveElement.clientHeight;

const masterHeight = masterScrollHeight - masterClientHeight;
const slaveHeight = slaveScrollHeight - slaveClientHeight;
/*
console.log({
  masterScrollHeight,
  slaveScrollHeight,
  masterClientHeight,
  slaveClientHeight,
  masterHeight,
  slaveHeight
});
*/
let interval = window.setInterval(function() {
  const currentMasterScrollTop = masterElement.scrollTop;
  const newMasterScrollTop = currentMasterScrollTop   stepSize;
  if (newMasterScrollTop > masterHeight) {

    window.clearInterval(interval);
    interval = null;
  }

  const percentageMasterDone = newMasterScrollTop / masterHeight;
  const newSlaveScrollTop = Math.ceil(percentageMasterDone * slaveHeight);
  /*
    console.log({
      currentMasterScrollTop,
      newMasterScrollTop,
      percentageMasterDone,
      newMasterScrollTop,
      newSlaveScrollTop
    });
    */
  masterElement.scrollTo({
    top: newMasterScrollTop
  });
  slaveElement.scrollTo({
    top: newSlaveScrollTop
  })

}, masterSpeed); //THIS WILL RUN IN EVERY 50 MILISECONDS
.container {
  display: flex;
}

span {
  display: block;
  height: 3px;
  background: red;
}

.box1 {
  width: 100px;
  height: 200px;
  overflow-y: auto;
  border: 2px solid blue;
  margin: 10px;
}

.box2 {
  width: 200px;
  height: 300px;
  overflow-y: auto;
  border: 2px solid blue;
  margin: 10px;
}
<div class="container">
  <div class="box1" id="master-box">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur,
    adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur
    sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam
    autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!<span></span></div>
  <div class="box2" id="slave-box">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur,
    adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur
    sequi harum sunt adipisci aperiam autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Qui, aspernatur sequi harum sunt adipisci aperiam
    autem perspiciatis quidem delectus corporis nulla modi sit id, odit minus. Natus tenetur iusto temporibus!<span></span></div>
</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related