javascriptjqueryscrolljquery-waypoints

waypoints on multiple elements - updating header


I am using waypoints to change a headers text as the user scrolls down a list of images. As the image scrolls to 50% viewport height (50vh) the related text set by its data-title attribute is used to update the main header.

It works ok as you scroll down, but when you scroll up the headers are out of sync - I want the header to only show when its over the relevant image.

var headerPoint = $(".project").waypoint(
  function(direction) {
    var title = this.element.getAttribute("data-title");
    $("#header").text(title);
  },
  {
    offset: "50%"
  }
);
h1 {
  position:fixed;
left: 50%;
top:50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%)
-webkit-transform: translateY(-50%);
transform: translateY(-50%)
  text-align:center;
}

#projects {
  margin:0 auto;
  width:400px;
  padding-top:400px;;
}
.project {
  background:pink;
  width:400px;
  height:600px;
  margin-bottom:100px;
}



* {
  margin:0;
  padding:0;
  box-sizing: border-box
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.js"></script>

<h1 id="header">Header one</h1>

<div id="projects">
  <div data-title="Header one" class="project">1</div>
  <div data-title="Header two" class="project">2</div> 
  <div data-title="Header three" class="project">3</div> 
  <div data-title="Header four" class="project">4</div>  
</div>


Solution

  • You can set two waypoints and check the direction.

    For going down you have correct, and for going up my solution changes header when bottom of div hits bottom of viewport. Not when hits bottom of header.

    You can try out some other offset values and I'm sure you'll get to exactly what you want. Here is a handy documentation

    Here is an working example

    var headerPoint = $(".project");
    
    headerPoint.waypoint({
      handler: function(direction) {
        if (direction === 'down') {
          var title = this.element.getAttribute("data-title");
          $("#header").text(title);
        }
      },
      offset: '50%'
    });
    
    headerPoint.waypoint({
      handler: function(direction) {
        if (direction === 'up') {
          var title = this.element.getAttribute("data-title");
          $("#header").text(title);
    
          //console.log($(window).height());
          //console.log(this.element.clientHeight);
        }
      },
      offset: 'bottom-in-view'
    });
    h1 {
      position: fixed;
      left: 50%;
      top: 50%;
      -webkit-transform: translateX(-50%);
      transform: translateX(-50%) -webkit-transform: translateY(-50%);
      transform: translateY(-50%) text-align:center;
    }
    
    #projects {
      margin: 0 auto;
      width: 400px;
      padding-top: 400px;
      ;
    }
    
    .project {
      background: pink;
      width: 400px;
      height: 600px;
      margin-bottom: 100px;
    }
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.js"></script>
    
    <h1 id="header">Header one</h1>
    
    <div id="projects">
      <div data-title="Header one" class="project">1</div>
      <div data-title="Header two" class="project">2</div>
      <div data-title="Header three" class="project">3</div>
      <div data-title="Header four" class="project">4</div>
    </div>

    EDIT

    Now it works exactly the way you wanted (when going up triggers when bottom in the middle of the screen).

    var headerPoint = $(".project");
    
    headerPoint.waypoint({
      handler: function(direction) {
        if (direction === 'down') {
          var title = this.element.getAttribute("data-title");
          $("#header").text(title);
        }
      },
      offset: '50%'
    });
    
    headerPoint.waypoint({
      handler: function(direction) {
        if (direction === 'up') {
          var title = this.element.getAttribute("data-title");
          $("#header").text(title);
    
          //console.log($(window).height());
          //console.log(this.element.clientHeight);
        }
      },
      offset: function() {
        return -this.element.clientHeight + ($(window).height()/2);
      }
    });
    h1 {
      position: fixed;
      left: 50%;
      top: 50%;
      -webkit-transform: translateX(-50%);
      transform: translateX(-50%) -webkit-transform: translateY(-50%);
      transform: translateY(-50%) text-align:center;
    }
    
    #projects {
      margin: 0 auto;
      width: 400px;
      padding-top: 400px;
      ;
    }
    
    .project {
      background: pink;
      width: 400px;
      height: 600px;
      margin-bottom: 100px;
    }
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.js"></script>
    
    <h1 id="header">Header one</h1>
    
    <div id="projects">
      <div data-title="Header one" class="project">1</div>
      <div data-title="Header two" class="project">2</div>
      <div data-title="Header three" class="project">3</div>
      <div data-title="Header four" class="project">4</div>
    </div>