jqueryscrollscope

Why can't I set this variable from undefined to the data I capture in the conditional statement?


What I am trying to do is move an element in accordance with the scroll top movement, once it appears in the browser. I am trying to capture an initial scroll top value and save that for some math on the object. The problem is that my variable remains undefined even though it appears to be set in the function.

I am using several scroll functions and that, and/or scope, might be my issues.

jQuery(document).ready(function($){

  //function that indicates object is in view
  $.fn.isInViewport = function() {
    var elementTop = $(this).offset().top;
    var elementBottom = elementTop + $(this).outerHeight();
    var viewportTop = $(window).scrollTop();
    var viewportBottom = viewportTop + $(window).height();
    return elementBottom > viewportTop && elementTop < viewportBottom;
  };

  //add class when object in is view
  jQuery(window).bind('scroll',function(e){
    if ($('.home-col-01-image').isInViewport()) {
      $('.home-col-01-image').addClass("in-view")
    } else {
      $('.home-col-01-image').removeClass("in-view")
    }
  });

  //use scrollTop to move object in parallel
  jQuery(window).bind('scroll',function(e){
    if ($(".home-col-01-image").hasClass("in-view")) {
      console.log("First initialSt: " + initialSt )
      if(initialSt == undefined) {
        var initialSt = $(this).scrollTop();
        console.log("Set initialSt: " + initialSt )
      } else {
        console.log("not set initialSt: " + initialSt)
      }
      //console.log("in: ")
      var st = $(this).scrollTop();
      var nst = st - initialSt;
      //var nst = Math.abs(initialSt - st)
      console.log("Use initialSt: " + initialSt)
      console.log("scrollTop: " + st)
      console.log("New scrollTop: " + nst)
      if ((nst<=170) && (nst>=0)) {
        $(".home-col-01-image").css("bottom", + nst);
      }
    } else {
      //console.log("out: ")
    }

 });



});

Here is sample of the console. The first occurrence of "First initialSt" should be undefined, but the second occurrence should not. I am setting that variable and outputting it at "Set initialSt," but when it comes back around it's still undefined.

First initialSt: undefined
Set initialSt: 1047
Use initialSt: 1047
scrollTop: 1047
New scrollTop: 0
First initialSt: undefined
Set initialSt: 1048
Use initialSt: 1048
scrollTop: 1048
New scrollTop: 0

My issues is the variable not being set, not necessarily how junky my code is, or how i could be doing this better.

This is my first Stack Question, so please let me know if I should be explaining more or less. Thanks!


Solution

  • You need to move the declaration of initialSt out of the event handler function, so it will persist between calls.

    It's also 2024. Use up-to-date jQuery methods, and let rather than var to declare variables.

    jQuery(document).ready(function($) {
    
      //function that indicates object is in view
      $.fn.isInViewport = function() {
        let elementTop = $(this).offset().top;
        let elementBottom = elementTop + $(this).outerHeight();
        let viewportTop = $(window).scrollTop();
        let viewportBottom = viewportTop + $(window).height();
        return elementBottom > viewportTop && elementTop < viewportBottom;
      };
    
      //add class when object in is view
      $(window).on('scroll', function(e) {
        if ($('.home-col-01-image').isInViewport()) {
          $('.home-col-01-image').addClass("in-view")
        } else {
          $('.home-col-01-image').removeClass("in-view")
        }
      });
    
      let initialSt;
      
      //use scrollTop to move object in parallel
      $(window).on('scroll', function(e) {
        if ($(".home-col-01-image").hasClass("in-view")) {
          console.log("First initialSt: " + initialSt)
          if (initialSt === undefined) {
            initialSt = $(this).scrollTop();
            console.log("Set initialSt: " + initialSt)
          } else {
            console.log("not set initialSt: " + initialSt)
          }
          //console.log("in: ")
          let st = $(this).scrollTop();
          let nst = st - initialSt;
          //var nst = Math.abs(initialSt - st)
          console.log("Use initialSt: " + initialSt)
          console.log("scrollTop: " + st)
          console.log("New scrollTop: " + nst)
          if ((nst <= 170) && (nst >= 0)) {
            $(".home-col-01-image").css("bottom", +nst);
          }
        } else {
          //console.log("out: ")
        }
      });
    });