Hide / show div on scroll, within another scroll function

I have a navbar that is fixed at a specific height (done by cloning the original navbar container and only displaying the clone after scrolling).

This nav container (ad) has a div that I want to hide whenever the user scrolls down and reappears when scrolling up. However, I was not successful!

Basic HTML Navigator:

<div class="toolbar-container">
  <div class="nav-ad"> ... </div>
  <div class="toolbar"> link 1 β€’ link 2 β€’ link 3 ... </div>
</div>

      

My code that doesn't work:

$(window).scroll(function() {
 if ($(this).scrollTop()>0) {
    $('.cloned.nav-ad').fadeOut();
 } else {
    $('.cloned.nav-ad').fadeIn();
 }
});

      

jQuery for cloned navbar (great solution from http://codepen.io/senff/pen/ayGvD so it doesn't jump):

$('.toolbar-container').addClass('original').clone().insertAfter('.toolbar-container').addClass('cloned').css('position','fixed').css('top','0').css('margin-top','0').css('z-index','500').removeClass('original').hide();

scrollIntervalID = setInterval(stickIt, 10);
function stickIt() {

  var orgElementPos = $('.original').offset();
  orgElementTop = orgElementPos.top;

  if ($(window).scrollTop() >= (orgElementTop)) {

    // scrolled past the original position; now only show the cloned, sticky element.
    // Cloned element should always have same left position and width as original element.

   orgElement = $('.original');
   coordsOrgElement = orgElement.offset();
   leftOrgElement = coordsOrgElement.left;
   widthOrgElement = orgElement.css('width');

  $('.cloned').css('left',leftOrgElement+'px').css('top',0).css('width', widthOrgElement).show();
  $('.original').css('visibility','hidden');
} else {
  // not scrolled past the menu; only show the original menu.
  $('.cloned').hide();
  $('.original').css('visibility','visible');
}
});

      

Am I on the right track here? The ad and toolbar are both flexible at the same time. The links in the navbar show a dropdown on hover (which also works fine). You just can't understand nav-ad!

+3


source to share


2 answers


First you pointed out that the wrong selector was gone, you missed the distance between the two classes to make it like $('.cloned .nav-ad')

.

Also if you want to fade out (in / out) depending on the scroll you need to compare with the last value window.scrollTop()

to show / hide your nav ad.

Below is a working example:



$(document).ready(function(){

  $('.toolbar-container').addClass('original').clone().insertAfter('.toolbar-container').addClass('cloned').css('position','fixed').css('top','0').css('margin-top','0').css('z-index','500').removeClass('original').hide();
  var scroll =0;
  $(window).scroll(function() {
   
   if ($(this).scrollTop()>scroll) {
      $('.cloned .nav-ad').fadeOut();
      scroll = $(this).scrollTop();
   } else {
      $('.cloned .nav-ad').fadeIn();
      scroll = $(this).scrollTop();
   }
  });
  
  scrollIntervalID = setInterval(stickIt, 10);
  function stickIt() {
    var orgElementPos = $('.original').offset();
    orgElementTop = orgElementPos.top;

    if ($(window).scrollTop() >= (orgElementTop)) {

        // scrolled past the original position; now only show the cloned, sticky element.
        // Cloned element should always have same left position and width as original element.

       orgElement = $('.original');
       coordsOrgElement = orgElement.offset();
       leftOrgElement = coordsOrgElement.left;
       widthOrgElement = orgElement.css('width');

      $('.cloned').css('left',leftOrgElement+'px').css('top',0).css('width', widthOrgElement).show();
      $('.original').css('visibility','hidden');
    } else {
      // not scrolled past the menu; only show the original menu.
      $('.cloned').hide();
      $('.original').css('visibility','visible');
    }
  }
});
      

.toolbar-container {
  background-color:#02a;
  padding:5px;
}

.nav-ad {
  float:right;
  color:white;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div><h2>This is a banner</h2></div>
<div class="toolbar-container">
  <div class="nav-ad">ad goes here </div>
  <div class="toolbar"> link 1 β€’ link 2 β€’ link 3 ... </div>
  
</div>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p><p>parag parag parag parga</p>
<p>parag parag parag parga</p>
<p>parag parag parag parga</p>
      

Run code


+1


source


Reasons why your code is not working:

  • You are trying to select .toolbar-container

    before loading the DOM. Encapsulate your code in $(function(){/* DOM queries here */})

    so that it only runs when the DOM is ready.
  • There is a syntax error in your code: there is an extra closing parenthesis on the last line. You can use your browser's console to check your code for syntax errors.

As for your code hiding your code, you are running out of space in your selector since yours .nav-ad

is inside an element .cloned

. It should be:

$(window).scroll(function() {
 if ($(this).scrollTop() > 0) {
    $('.cloned .nav-ad').fadeOut();
 } else {
    $('.cloned .nav-ad').fadeIn();
 }
});

      

However, let me explain why you should change the code anymore. The way your code is written is very inefficient. To optimize your code, consider the following:



  • Always initialize all your variables with var

    , let

    or const

    . Undeclared variables are implied as global variables, which are very error prone and generally bad practice.
  • Don't use setInterval () for this operation. It's super ineffective. Use an event handler instead onScroll

    .
  • Don't let element classes identify them. Instead, store them in a variable. This way you don't have to constantly fire new DOM queries.
  • Do not take measurements that remain constant inside an event handler. Instead, measure once and store them in a variable outside the handler.
  • Do not click .css()

    on the same element several times in succession. Instead, pass the functions to the object with whatever styles you want to apply.

Here's the working code:

$(function() {
  var $window = $(window);
  var $toolbarOriginal = $('.toolbar-container');
  var $toolbarClone = $toolbarOriginal
    .clone()
    .css({
      position: 'fixed',
      top: 0,
      marginTop: 0,
      zIndex: 500,
    }).hide().insertAfter($toolbarOriginal);
  var $adClone = $toolbarClone.find('.nav-ad');

  var orgElementPos = $toolbarOriginal.offset();

  $window.scroll(function(e) {
    $window.scrollTop() >= orgElementPos.top ? attach() : detach();
  });

  function attach() {
    $toolbarOriginal.css('visibility', 'hidden');
    $toolbarClone.show().css({
      left: orgElementPos.left,
      width: $toolbarOriginal.css('width'),
      top: 0,
    });
    $adClone.fadeOut();
  }

  function detach() {
    $toolbarOriginal.css('visibility', 'visible');
    $toolbarClone.hide();
    $adClone.fadeIn();
  }
});

      

Also, here's a demo .

Also, something to consider: most ad units automatically block elements with classes containing the word "ad".

+1


source







All Articles