0

I am somewhat familiar with waypoints and tried setting it up to work for the following.

I am trying to get #bundler-offer to display after the user clicks on the radio button for Option 2. The blue div #bundle-offer should fade in, however the waypoints is registering on page load - as you can see in the console.

What do I have to do to only get the waypoints to show when the #review-main is in view?

Jsfiddle

var package1 = $('#package1');
var package2 = $('#package2');
$('.product').on('change', function() {
  if (package1.is(':checked')) {
    console.log("Option - Package 1");
    $('#pack2-details').hide();
    $('#pack1-details').show();
  } else if (package2.is(':checked')) {
    console.log("Option - Package 2");
    $('#pack2-details').show();
    $('#pack1-details').hide();
  }
});
$('#review-main').waypoint(function() {
  // handler: function(direction) {
  $('#bundle-offer').addClass('fadeUp');
  console.log('Scrolled to waypoint!');
}, {
  offset: '100%'
});
.check {
  display: none;
}

.wrap {
  background: green;
  height: 600px;
  width: 100%;
}

#bundle-offer {
  position: fixed;
  bottom: -120px;
  left: 0;
  right: 0;
  width: 100%;
  height: 120px;
  background: blue;
  opacity: 0;
  transition: all 0.5s ease;
}

#bundle-offer.fadeUp {
  opacity: 1;
  transition: all 0.5s ease;
  bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.min.js"></script>
<label>Option 1</label>
<input type="radio" class="product" id="package1">
<label>Option 2</label>
<input type="radio" class="product" id="package2">
<div id="pack1-details" class="check">
  <p>Package 1</p>
  <div class="wrap" id="pack1-details">
    Package 1 showing
  </div>
</div>
<div id="pack2-details" class="check">
  <p>Package 2</p>
  <div class="wrap" id="pack2-details">
    Package 2 showing
    <div id="review-main">
      <div id="bundle-offer">Working IF fading in</div>
    </div>
  </div>
</div>
Paul
  • 3,348
  • 5
  • 32
  • 76
  • Possible duplicate of [Check if element is visible after scrolling](http://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling) – Rax Weber Mar 24 '17 at 16:58
  • @RaxWeber I am using waypoints? How in the world is this a possible duplicate? I have a detailed issue. – Paul Mar 24 '17 at 16:59
  • @RaxWeber I just tried using the solution from the question you referred me to. The issue remains the same... the blue box `#bundler-offer` doesn't initiate when the div is in view. https://jsfiddle.net/hvskg9s3/ ...... It still shows the div id in view before it actually is. – Paul Mar 24 '17 at 17:05
  • @RaxWeber - I don't think this is a duplicate (not sure why you'd think so either) but the resolution to the issue is covered elsewhere on SO [here](http://stackoverflow.com/questions/30961414/why-jquery-waypoints-bottom-in-view-doesnt-work-on-hidden-elements) – wahwahwah Mar 24 '17 at 17:08

1 Answers1

1

This is covered in the waypoints debugging documentation and also addressed elsewhere on SO.

Here's the explanation from waypoints:

[...] When Waypoints is calculating the trigger point, it doesn't have a way to find the would-be-if-not-display-none position. The resulting calculation ends up incorrect, often with sporadic values.

You should never use a display:none element as a waypoint. This includes elements that gain display:none at any time in the lifetime of your page, as trigger points are recalculated whenever a refresh occurs, such as a window resize event.

[and because of this, you're waypoint function is firing on page load]

If you utilize opacity to hide the element, rather than display:none, waypoints should be able to locate the element:

Example from waypoints

$('.something')
  .css('opacity', 0) // immediately hide element
  .waypoint(function(direction) {
    if (direction === 'down') {
      $(this.element).animate({ opacity: 1 })
    }
    else {
      $(this.element).animate({ opacity: 0 })
    }
  }, {
    offset: 'bottom-in-view'
  });

If you implement this into your code and change the css on page load accordingly, you should get the behavior you're looking for.

Edit:

While not elegant, I think this code snippet essential applies the waypoint documentation to your issue. It may not be a perfect solution for your use-case, but certainly responds to your comment below.

fiddle

Here's what's changed in a nutshell:

  1. Instead of "show/hide" this code uses "opacity"
  2. The waypoint trigger element is added through jQuery (and removed,) otherwise the zero opacity element still occupies space and triggers the waypoint. The same thing could be accomplished by binding/unbinding the waypoint
  3. Some of the css/html needed cleaning up - if avoidable, try not to use more than one instance of the same element id (you should never have this problem if it's all your own html.)
  4. Used a "name" field on your radio inputs so only one can be selected at a time.

And, code for posterity:

$("input[name='prod_op']").on('change', function() {
  console.log($(this).attr('id'));
  if ($(this).attr('id') === "package1" && $('#pack1-container').css('opacity', 0)) {
    console.log('selected 1');
    $('#pack1-container').css({
      'opacity': 1,
      'height': '600px'
    });
    $('#pack2-container').css({
      'opacity': 0,
      'height': '0px'
    });
    $('#pack2-details').empty();
  } else if ($(this).attr('id') === "package2" && $('#pack2-container').css('opacity', 0)) {
    console.log('selected 2');
    $('#pack2-container').css({
      'opacity': 1,
      'height': '600px'
    });
    $('#pack1-container').css({
      'opacity': 0,
      'height': '0px'
    });
    $('#pack2-details').append('Package 2 showing <div id="review-main"><div id="bundle-offer" class="hide">Working IF fading in</div></div>');
    setWaypoint();
  }
});

var setWaypoint = function(){
  var waypoint = new Waypoint({
    element: $('#review-main'),
    handler: function(direction){
      if(direction === "down"){
        console.log('waypoint... down');
        $('#bundle-offer').removeClass('hide fadeDown').addClass('fadeUp');
      } else if(direction === "up") {
        console.log('waypoint... up');
        $('#bundle-offer').removeClass('fadeUp').addClass('fadeDown');
        console.log('waypoint... down');
      }
    },
    //offset: '600px'
  });
}
.hide {
  opacity: 0;
  height: 0px;
}

.wrap {
  background: green;
  height: 600px;
  width: 100%;
  display: block;
}

#bundle-offer {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  height: 120px;
  background: blue;
  transition: all 0.5s ease;
}


.fadeUp {
  opacity: 1;
  transition: all 0.5s ease;
  bottom: 0;
}

.fadeDown{
  opacity: 0;
  transition: all 0.5s ease;
  bottom: 0;
}

.page_wrap{
  min-height: 1000px;
  background-color: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="page_wrap">

  <label>Option 1</label>
  <input type="radio" class="product" name="prod_op" id="package1" />
  <label>Option 2</label>
  <input type="radio" class="product" name="prod_op" id="package2" />

  <div id="pack1-container" class="hide">
    <p>Package 1</p>
    <div class="wrap" id="pack1-details">
      Package 1 showing
    </div>
  </div>

  <div id="pack2-container" class="hide">
    <p>Package 2</p>
    <div class="wrap" id="pack2-details">
    </div>
  </div>
</div>
Community
  • 1
  • 1
wahwahwah
  • 3,254
  • 1
  • 21
  • 40
  • I can't quite figure it out with my format. Any ideas? I only want the radio buttons to show, until you click on them. Then if option 2 is clicked for the waypoints to fire. https://jsfiddle.net/f0ua7wa8/7/ – Paul Mar 24 '17 at 17:20
  • Do you want both radios to be selectable at once? (both option 1 and option 2?) Or should it be either / or? – wahwahwah Mar 24 '17 at 17:34
  • Either or. I just want to hide the contents of both on page load. Then show the appropriate option content when radio button is clicked, but I only want the waypoint to trigger when review main is shown (in option 2) – Paul Mar 24 '17 at 17:42