fsn fusion fsn fusion - 3 years ago 161
CSS Question

Navbar Change on Scroll

Library/Frameworks used = Jquery+Bootstrap 4
I want to the navbar change on scroll (up and down) to a svg of the same size and responsiveness. This is my code so far.

As you can see i'm using. top to change de navbar, but i need it to change on scroll up and down without making top > 56 like this.



$(document).ready(function() {
var navpos = $("#navbar_scroll").offset().top;
$(window).scroll(function() {
let windowpos = $(this).scrollTop();
if (windowpos >= navpos) {
$("#navbar_scroll").addClass('navbar_style_2');
$("#navbar_scroll").removeClass('navbar_style_3');
console.log("up");
} else {
$("#navbar_scroll").addClass('navbar_style_3');
$("#navbar_scroll").removeClass('navbar_style_2');
console.log("down");
}
})
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="navbar_scroll" class="navbar navbar-toggleable-sm fixed-top navbar-inverse navbar_style">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand hidden-md-up" href="#"><img src="tps.jpg" class="img-fluid" style="width: 27px; height: 27px;"></a>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav mr-auto">
<a class="nav-item nav-link active " href="tu_pasion_click">1</a>
<a class="nav-item nav-link " href="tu_voz_click">2</a>
<a class="nav-item nav-link" href="#">3</a>
<a class="nav-item nav-link" href="#">4</a>
<a class="nav-item nav-link" href="#">5</a>
</div>
<a class="navbar-brand hidden-sm-down" href="#"><img src="tps.jpg" class="img-fluid" style="width: 27px; height: 27px;"></a>
<div class="navbar-nav ml-auto">
<a class="nav-item nav-link" href="#">6</a>
<a class="nav-item nav-link" href="#">7</a>
<a class="nav-item nav-link" href="#">8</a>
<a class="nav-item nav-link" href="#">9</a>
<a class="nav-item nav-link" href="#">10</a>
</div>
</div>
</nav>




Answer Source

The Issue

In order to detect whether a user is actively scrolling we need to check to see whether how long since the last scroll event. Since we only want to fire the function the minimum number of times required we can use $.debounce.

Solution

The snippet demonstrates $.debounce by Ben Alman which detects the user's scroll. More accurately it detects when the event hasn't happened after a set amount of time and then fires the function. This will allow the function to fire once after the set number of milliseconds

$.debounce(delay, at_begin, callback)

Note, that at_begin is false by default:

(Boolean) Optional, defaults to false. If at_begin is false or unspecified, callback will only be executed delay milliseconds after the last debounced-function call. If at_begin is true, callback will be executed only at the first debounced-function call. (After the throttled-function has not been called for delay milliseconds, the internal counter is reset)

If at_begins is true, then the function will fire at the first function call (after the set delay).

If at_begins is false, then the function will fire once only after the last event was called (after the set delay)

Read more about $.debounce and $.throttle plugin

(function(window,undefined){
  '$:nomunge'; 
  var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ),

      jq_throttle;

  $.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) {

    var timeout_id,

        last_exec = 0;

    if ( typeof no_trailing !== 'boolean' ) {
      debounce_mode = callback;
      callback = no_trailing;
      no_trailing = undefined;
    }

    function wrapper() {
      var that = this,
          elapsed = +new Date() - last_exec,
          args = arguments;

      function exec() {
        last_exec = +new Date();
        callback.apply( that, args );
      };

      function clear() {
        timeout_id = undefined;
      };

      if ( debounce_mode && !timeout_id ) {
        exec();
      }

      timeout_id && clearTimeout( timeout_id );

      if ( debounce_mode === undefined && elapsed > delay ) {
        exec();

      } else if ( no_trailing !== true ) {

        timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay );
      }
    };

    if ( $.guid ) {
      wrapper.guid = callback.guid = callback.guid || $.guid++;
    }

    return wrapper;
  };

  $.debounce = function( delay, at_begin, callback ) {
    return callback === undefined
      ? jq_throttle( delay, at_begin, false )
    : jq_throttle( delay, callback, at_begin !== false );
  };

})(this);

//Here is the implementation of $.debounce
$(window).scroll($.debounce(0, true, function(){
  $('nav').addClass('hide');
}, 250));

$(window).scroll($.debounce( 250, function(){
  $('nav').removeClass('hide');
} ) );
body{
  height: 6000px;
}

.svg{
  position: fixed;
  top: 0;
  z-index: 20;
}

.mt-100{
  margin-top: 100px;
}

.hide{
  visibility: hidden;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
  <img class="svg" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/262726/pattern.svg" width="100%"/>
 <nav class="fixed-top navbar navbar-toggleable-md navbar-inverse bg-inverse">
    <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <a class="navbar-brand" href="#">Navbar</a>
    <div class="collapse navbar-collapse" id="navbarNav">
      <ul class="navbar-nav">
        <li class="nav-item active">
          <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Features</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Pricing</a>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled" href="#">Disabled</a>
        </li>
      </ul>
    </div>
  </nav>
<div class="container mt-100"><h1>Scroll Down</h1></div>
</body>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download