javascripthtmlcssscrollposition

How can i keep this div visible until it moves to its end position but scroll past it after it has moved to its end position?


I am able to make this div move right when scrolling but i want its position to be fixed while scrolling before it has reached its end position. The problem I am having is that when I scroll further after the movingDiv has reached its end position, the position continues to remain fixed.

const container = document.querySelector(".container");
const movingDiv = document.querySelector(".moving-div");
let scrollPosition = 0;
let endPosition = 0;

window.addEventListener("scroll", () => {
  let scrollPosition = window.scrollY;

  movingDiv.style.transform = scrollPosition <= endPosition ?
    `translateX(${scrollPosition}px)` :
    `translate(300px)`;

  // Stop movement when movingDiv reaches maxPosition

  if (movingDiv.offsetLeft >= movingDiv.maxPosition) {
    movingDiv.style.position = "absolute";
  } else {
    movingDiv.style.position = "fixed";
  }
});
.container {
  height: 200vh;
}

.moving-div {
  height: 100px;
  width: 100px;
  background-color: black;
  left: 0;
  transition: 0.3s right ease;
}
<div class="container">
  <div class="moving-div"></div>
</div>


Solution

  • Looks like you're checking movingDiv.offsetLeft >= movingDiv.maxPosition, but maxPosition isn't defined anywhere and offsetLeft gives the position relative to the parent, not the transformed position.

    Check it out:

      const container = document.querySelector(".container");
      const movingDiv = document.querySelector(".moving-div");
    
      // Define the maximum distance the div should move
      const maxMoveDistance = 300;
    
      window.addEventListener("scroll", () => {
        const scrollPosition = window.scrollY;
    
        if (scrollPosition <= maxMoveDistance) {
          // Moving phase - keep it fixed and translate based on scroll
          movingDiv.style.position = "fixed";
          movingDiv.style.transform = `translateX(${scrollPosition}px)`;
          movingDiv.style.top = "50px"; // Reset to original top position
        } else {
            // Past the moving phase - make it absolute at final position
            movingDiv.style.position = "absolute";
            movingDiv.style.transform = `translateX(${maxMoveDistance}px)`;
            movingDiv.style.top = `${maxMoveDistance + 50}px`; // Position it where it would naturally be
        }
      });
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Scroll Moving Div</title>
      <style>
        body {
            margin: 0;
            padding: 0;
        }
    
        .container {
            height: 300vh; /* Made taller to test scrolling past */
        }
    
        .moving-div {
            height: 100px;
            width: 100px;
            background-color: black;
            left: 0;
            top: 50px;
            position: fixed;
            transition: none; /* Remove transition for smooth scroll-based movement */
        }
    
        .content {
            padding: 20px;
            margin-top: 200px;
        }
    
        .content h2 {
            margin-bottom: 20px;
        }
    
        .content p {
            margin-bottom: 15px;
            line-height: 1.6;
        }
      </style>
    </head>
    <body>
      <div class="container">
        <div class="moving-div"></div>
        <div class="content">
          <h2>Scroll to see the div move</h2>
          <p>The black div will move right as you scroll down, staying fixed in position.</p>
          <p>Once it reaches its end position (300px), it will become absolute positioned and you can scroll past it normally.</p>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
          <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
          <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
          <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
          <p>Continue scrolling to see the div become scrollable once it reaches the end...</p>
          <p>More content here to demonstrate scrolling past the div...</p>
          <p>Even more content to show normal scrolling behavior...</p>
          <p>Final content section...</p>
        </div>
      </div>
    </body>
    </html>