Background image not changing properly with 'Offset' in Waypoints.js

137 Views Asked by At

Here is some Javascript and CSS from my program:

<script>
var $body = $('body');


$body.waypoint(function (direction) {
  if (direction == 'down') {
      $body.addClass('body2'); 
  } else{
      $body.removeClass('body2');
  }
}, { offset: '50%'});


</script>   


    
    
<style>
body {
  background-image: url("images/image1.png");
  background-repeat: no-repeat;
  background-position: 400px 200px;
  background-size: 900px 300px;
  margin-right: 400px;
  background-attachment: fixed;
}


.body2 {
  background-image: url("images/image2.png");
  background-repeat: no-repeat;
  background-position: 400px 200px;
  background-size: 900px 300px;
  margin-right: 400px;
  background-attachment: fixed;
}

I'm trying to change the background image from image1 (body) to image2 (body2) as I scroll 50% of the way down the page. However, when I launch the program the only image displayed is image2 and nothing changes as I scroll. Any help would be greatly appreciated, thanks in advance!

2

There are 2 best solutions below

0
On BEST ANSWER

I've actually figured out the problem. All I needed to do was set the offset percentage as negative.

0
On

I tried to use waypoints, but I can't seem to make it work though (it gives unreliable results for me, on Chrome).

You could use your own custom function to handle the scroll event as you wish. You need to compute:

  • height: total document height (offset 50% = height/2)
  • y: current scroll position
  • direction: by comparing y with the last scroll position

Like in this example (Run code snippet):

/**
 * very simple on scroll event handler
 * use: Scroller.onScroll(..custom function here...)
 * custom function gets 3 parameters: y, height and direction
 */
var Scroller = {
  _initiated: 0,
  _init: function() {
    var t = this;
    t._listener = function() {
      t._scrollEvent();
    };
    window.addEventListener("scroll", t._listener);
    t.y = t.getY();
    t._initiated = 1;
  },
  _onScroll: null,
  _scrollEvent: function() {
    var t = this;
    if (!t._initiated || !t._onScroll)
      return false;
    var y = t.getY();
    t.height = document.body.scrollHeight;
    t.direction = y < t.y ? "up" : "down";
    t.y = y;
    t._onScroll(t.y, t.height, t.direction);
  },
  getY: function() {
    //for cross-browser compatability
    // https://stackoverflow.com/a/51933072/4902724
    return (window.pageYOffset !== undefined) ?
      window.pageYOffset :
      (document.documentElement || document.body.parentNode || document.body).scrollTop;
  },
  onScroll: function(fn) {
    var t = this;
    t._onScroll = fn;
    if (!t._initiated)
      t._init();
  },
  destroy: function() {
    var t = this;
    window.removeEventListener("scroll", t._listener);
    t._onScroll = null;
    t._initiated = 0;
  }
};
/**
 * global vars
 */
var $body = $("body");
// keep track of changes, to cancel unnecessary class changes
$body.classChanged = 0;
/**
 * on scroll setup
 */
Scroller.onScroll(function(y, height, direction) {
  /* to check for 50%, compare y vs. height/2 */
  if (y > height / 2 && direction == "down" && !$body.classChanged) {
    $body.addClass("body2");
    $body.classChanged = 1;
  }
  if (y < height / 2 && direction == "up" && $body.classChanged) {
    $body.removeClass("body2");
    $body.classChanged = 0;
  }
});
body {
  background-color: lightgreen;
}

.body2 {
  background-color: gold;
}


/* demo helpers...*/

div {
  float: left;
  width: 100%;
  height: 250px;
  border: 1px solid grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Sroll down below 50% to change body color...."</p>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>

Hope this helps, even without that plugin.