Search code examples
javascripthtmlcssdomscroll

How to control scrolling of an element scrolling another


As you can see the structure of my html, I am trying to position the cursor in the left column of the screen and scroll down so that instead of scrolling inside the body and going to the footer, i want it to scroll the right side. And when the content ends, the footer of my page is displayed. I don't know if I understood myself but I want the content of the right column to be shown specifically when I position myself in both columns and scroll.

Here I show my html, css and JavaScript code. Perhaps something is preventing the action I want to do. Yet, at the moment I don´t have any other ideas.

document.addEventListener('DOMContentLoaded', function() {
  var column1 = document.getElementById('column-1');
  var column2 = document.getElementById('column-2');

  column1.addEventListener('scroll', function() {
    column2.scrollTop = column1.scrollTop;
  });
});
html {
  height: 100%;
  width: 100%;
  background-color: brown;
}

body {
  height: 100%;
  width: 100%;
  margin: 0;
}

.content {
  background-color: bisque;
  display: flex;
  height: 100vh;
  overflow-y: auto;
}

.column-1 {
  width: 50%;
  text-align: center;
  border-right: 1px solid brown;
  overflow-y: auto;
  max-height: 100vh;
}

.brownie-img-container {
  overflow: auto;
  width: 100%;
  height: 100%;
}

.title {
  margin: 0;
}

.brownie-img {
  width: 50%;
  border-radius: 50%;
  margin-top: 25vh;
}

.column-2 {
  width: 50%;
  text-align: center;
  padding: 10px;
  font-family: 'IBM Plex Sans', sans-serif;
  overflow-y: auto;
  max-height: 100vh;
}

.description {
  text-align: justify;
}
<div class="content" id="content">
  <div class="column-1" id="column-1">
    <img class="brownie-img" src="https://i.postimg.cc/xqDLpZxp/7e8da6ab74a9-brownie-de-chocolate-con-leche.png" alt="Brownie de Cacao">
  </div>
  <div class="column-2" id="column-2">
    <h1>Brownie de Cacao</h1>
    <h2>Descripción</h2>
    <div class="description">
      <p>"Lorem Ipsum Content..."</p>
    </div>
  </div>
</div>
<footer>
  <div class="footer-content">
    <p>&copy; 2023 Mi Sitio Web. Todos los derechos reservados.</p>
    <ul>
      <li><a href="#">Política de privacidad</a></li>
      <li><a href="#">Términos y condiciones</a></li>
    </ul>
  </div>
</footer>


Solution

  • First, I added some content so a scroll bar would appear. My idea is to use the deltaY parameter of the wheel event handler in order to cancel it without invoking scroll.

    document.addEventListener('DOMContentLoaded', function() {
      var column1 = document.getElementById('column-1');
      var column2 = document.getElementById('column-2');
    
      column1.addEventListener('wheel', function(ev) {
        column2.scrollTop += ev.deltaY;
        ev.preventDefault();
      });
    });
    html {
      height: 100%;
      width: 100%;
      background-color: brown;
    }
    
    body {
      height: 100%;
      width: 100%;
      margin: 0;
    }
    
    .content {
      background-color: bisque;
      display: flex;
      height: 100vh;
      overflow-y: auto;
    }
    
    .column-1 {
      width: 50%;
      text-align: center;
      border-right: 1px solid brown;
      overflow-y: auto;
      max-height: 100vh;
    }
    
    .brownie-img-container {
      overflow: auto;
      width: 100%;
      height: 100%;
    }
    
    .title {
      margin: 0;
    }
    
    .brownie-img {
      width: 50%;
      border-radius: 50%;
      margin-top: 25vh;
    }
    
    .column-2 {
      width: 50%;
      text-align: center;
      padding: 10px;
      font-family: 'IBM Plex Sans', sans-serif;
      overflow-y: auto;
      max-height: 100vh;
    }
    
    .description {
      text-align: justify;
    }
    <div class="content" id="content">
      <div class="column-1" id="column-1">
        <img class="brownie-img" src="https://i.postimg.cc/xqDLpZxp/7e8da6ab74a9-brownie-de-chocolate-con-leche.png" alt="Brownie de Cacao">
      </div>
      <div class="column-2" id="column-2">
        <h1>Brownie de Cacao</h1>
        <h2>Descripción</h2>
        <div class="description">
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
        </div>
      </div>
    </div>
    <footer>
      <div class="footer-content">
        <p>&copy; 2023 Mi Sitio Web. Todos los derechos reservados.</p>
        <ul>
          <li><a href="#">Política de privacidad</a></li>
          <li><a href="#">Términos y condiciones</a></li>
        </ul>
      </div>
    </footer>

    This is just an example, the actual movement is jumpy. But I think I have another thing with scroll I've answered in the past. How to create smooth movement while mouse scrolling?

    I'll incorporate this:

    var column1 = document.getElementById('column-1');
    var column2 = document.getElementById('column-2');
    
    
    
    var speed = 0;
    var lastUpdateTime = 0;
    
    // try different numbers
    var speedFactor = 5 
    
    // must be active (not passive)
    column1.addEventListener('wheel', function(ev) {
      speed = ev.deltaY / speedFactor;
      ev.preventDefault();
    }, {
      passive: false
    })
    
    // a bad usage of the gameLoop...
    function update(deltaTime) {
      const easingFactor = 0.9;
      speed *= easingFactor;
    }
    
    // this probably rounds the speed...
    function render() {
      column2.scrollTop += speed
    }
    
    function gameLoop(currentTime) {
      const deltaTime = currentTime - lastUpdateTime;
      update(deltaTime);
      render();
      lastUpdateTime = currentTime;
      requestAnimationFrame(gameLoop);
    }
    
    
    requestAnimationFrame(gameLoop);
    html {
      height: 100%;
      width: 100%;
      background-color: brown;
    }
    
    body {
      height: 100%;
      width: 100%;
      margin: 0;
    }
    
    .content {
      background-color: bisque;
      display: flex;
      height: 100vh;
      overflow-y: auto;
    }
    
    .column-1 {
      width: 50%;
      text-align: center;
      border-right: 1px solid brown;
      overflow-y: auto;
      max-height: 100vh;
    }
    
    .brownie-img-container {
      overflow: auto;
      width: 100%;
      height: 100%;
    }
    
    .title {
      margin: 0;
    }
    
    .brownie-img {
      width: 50%;
      border-radius: 50%;
      margin-top: 25vh;
    }
    
    .column-2 {
      width: 50%;
      text-align: center;
      padding: 10px;
      font-family: 'IBM Plex Sans', sans-serif;
      overflow-y: auto;
      max-height: 100vh;
    }
    
    .description {
      text-align: justify;
    }
    <div class="content" id="content">
      <div class="column-1" id="column-1">
        <img class="brownie-img" src="https://i.postimg.cc/xqDLpZxp/7e8da6ab74a9-brownie-de-chocolate-con-leche.png" alt="Brownie de Cacao">
      </div>
      <div class="column-2" id="column-2">
        <h1>Brownie de Cacao</h1>
        <h2>Descripción</h2>
        <div class="description">
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
          <p>"Lorem Ipsum Content..."</p>
        </div>
      </div>
    </div>
    <footer>
      <div class="footer-content">
        <p>&copy; 2023 Mi Sitio Web. Todos los derechos reservados.</p>
        <ul>
          <li><a href="#">Política de privacidad</a></li>
          <li><a href="#">Términos y condiciones</a></li>
        </ul>
      </div>
    </footer>