Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move element on page as user scrolls up and down

I am struggling to achieve what should be a simple task.

  1. Page Loads
  2. User freely scrolls down through different sections.
  3. When a specific DIV reaches the centre of the page I would like to pause/prevent scrolling down until the DIV has been moved horizontally across to the left a fixed number of pixels.
  4. Then the user can be allowed to continue scrolling down the page.

Also, I would like to achieve the opposite effect if the user scrolls up i.e. scroll the div to the right a fixed number of pixels before continuing up.

Below is a sample of my code.

$(window).scroll(function() {
    sD = $(this).scrollTop();

    // $('.features-2-item').width();
    if (sD > (f2Pos.top + 100) && sD < f2Pos.top + 2000 + 100) {

        // if scroll distance is greater than the top position of
        // the statements when they are centred in the viewport,
        // and less than the top position of statements centred 
        // plus the height of 4 statements, prevent user from 
        // scrolling, then run function to change statements.
        sD = f2Pos.top + 100;
        var scroll = $(window).scrollTop();
        // console.log(('up or down: ' + xSlide + ' > - ' + statementWidth + ' || ' + scroll + ' < ' + position));
        if (xSlide > -statementWidth || scroll < position) {
            slideStatements();
        }
    }

    if (sD > f2Pos.top + 2000) {
        // if scroll distance is greater than the top positon of
        // the statements, centred in the viewport, plus the   
        // height of 4 statements, the user has scrolled through    
        // all of the statements and should be allowed to resume   
        // scrolling. Scrolling should be adjusted to take away  
        // the distance equal to the height of 4 statements.
        sD = sD - 2000 + 100;
    }

});

var statementWidth = $('.features-2-item').width();
var xSlide = statementWidth;

var position = $(window).scrollTop();


function slideStatements() {
    var st = $(this).scrollTop();
    if (st > lST) {
        // Going Down
        if (cS) {
            // disallow scrolling until after statement slides
            cS = false;
            xSlide = Math.floor(xSlide + 32);
            $(window).one('scroll.slideStatements', function() {

                $(".features-2-container").css("transform", "translateX(" + xSlide + "px)");
            });
            // allow scrolling after statement slides
            cS = true;

        }
    } else {
        // Going Up
        if (cS) {
            // disallow scrolling until after statement slides
            cS = false;

            xSlide = Math.floor(xSlide - 32);

            $(window).one('scroll.slideStatements', function() {
                // $sS.slick("slickPrev");
                $(".features-2-container").css("transform", "translateX(" + xSlide + "px)");
            });
            // allow scrolling after statement slides
            cS = true;

        }
    }
    lST = st - 1;
}

Any suggestion swould be great.

regards

like image 560
stato74 Avatar asked Oct 28 '25 12:10

stato74


1 Answers

Hi I'm not an expert here but I would like to share my method.

In my opinion the hardest part is how to prevent the scrolling. So we are not going to prevent it, instead we are going to take some advantage of it.

Let's say we have 3 sections like

<section>...</section>
<section class='stuart'>
  <div class='kevin'></div>
</section>
<section>...</section>

And style like

.stuart {
  height: 600px;
}

.kevin {
  position: absolute;
  width: 50px;
  height: 50px;
  background: tomato;
}

So stuart is a our container and kevin is a box inside.

Our goal is simple, when kevin goes up and pass the middle of window we will keep it at that middle (vertical) and move it from left to right (horizontal) until the end of stuart pass.

Code will be like

if (stuart.top < windowHeight / 2 &&
    stuart.top + stuart.height - kevin.height > windowHeight / 2) {

  let distance = windowHeight / 2 - stuart.top
  kevin.classList.add('fixed')
  kevin.style.left = distance + 'px'
}

The important part is the distance which always relate to the position of stuart, so you will no need to do anything about opposite effect.

Final example here.

Bad news, you need to calculate the height of container by yourself or a fixed position may not work in your case or other things but I hope this idea will help you in some way. Thanks.

like image 137
User 28 Avatar answered Oct 31 '25 00:10

User 28



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!