Search code examples
jqueryscrollscrolltop

How to print something when the user reaches a specific point in the page? (not dependant on any class or ID element)


I want to print something in the console log when the user reaches a certain point in the page. I want it to appear regardless of the classes or IDs of the page, just when it reaches a speciifc point and not to be repeated, specially not to repeat if the user goes up and scrolls down again.

In this example, if I use $this.scrollTop() > 400 it does work, but the console keeps repeating the message. So I thought using == instead, but it won't work.

Why? How can I get that sorted? Can this be achieved with vanilla JS?

$(window).scroll(function () {
    var $this = $(this),
        $head = $('#head');
    if ($this.scrollTop() == 400) {
       console.log('You've reached 400 already');
    }
});

Solution

  • Using > vs == (or ===) has no effect on the "one time only" logic you are trying to achieve. However, it is probably safer to use >, as browsers may not report every single pixel change when scrolling. What you're missing is some kind of state: that tracks if that comparison has been done before.

    If you only want to compare a single scroll position, then we can simply store if the user has scrolled past that point in a variable and check it, so we don't log to the console more than once:

    var hasPassedPoint = false;
    
    $(window).scroll(function() {
      var $this = $(this);
    
      if ($this.scrollTop() > 400 && !hasPassedPoint) {
        console.log('You\'ve reached 400 already');
        hasPassedPoint = true;
      }
    });
    p {
      margin-bottom: 200px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>

    If you want to compare multiple scroll positions though, that storing these state/checkpoints in an object might make more sense:

    var passedCheckpoints = {};
    var checkpoints = [150, 400, 550];
    
    $(window).scroll(function() {
      var $this = $(this);
    
      checkpoints.forEach(x => {
        if ($this.scrollTop() > x && !passedCheckpoints[x]) {
          console.log(`You've reached ${x} already`);
          passedCheckpoints[x] = true;
        }
      });
    });
    p {
      margin-bottom: 200px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>
    <p>Keep scrolling down</p>