简体   繁体   中英

Fix navbar to top of page when scrolling

I'm trying to make a navbar similar to the one on Linus Tech tips ( https://linustechtips.com/main/ ) for a school assignment. I'm at the real basic level of Javascript and I cooked up a pinnable navbar but when I made it there was no banner above it. Now there is a banner above it and I don't know how to make the navbar push to the top when I start scrolling. Here is my HTML:

<div class="navContainer">

    <div class="topBanner">

        <img src="images/topbanner.png" id="topBannerimg"/>

    </div>

    <div id="navbar">

        <button onclick="pinfunc()"><i id="pin" class="fa fa-thumb-tack fa-2x navButton" id="pinbtn" aria-hidden="true"></i></button>

    </div>

</div>

Here is my Javascript:

var pinned = 1;
    console.log(pinned);
function pinfunc() {


    if (pinned == 1) {
        document.getElementById("navbar").style.position= "relative";
        document.getElementById("pin").style.color = "black";
        document.getElementById("pin").style.transform = "rotate(0deg)";
        pinned=0;
    }
    else if (pinned == 0) {
        document.getElementById("navbar").style.position="fixed";
        document.getElementById("pin").style.color = "red";
        document.getElementById("pin").style.transform = "rotate(270deg)";
        pinned=1;
    }
}

And here is my CSS:

body{
    margin: 0 auto;
}

.navContainer{
    width: 100%;
    margin: 0 auto;
}

#topBannerimg{
    width: 100%;
    margin: 0;
    display:block
}

.navButton{
    height: 25px;
    width: 25px;
}

.fa-thumb-tack{
    font-size: 50px;
    color: red;
    transform: rotate(270deg);
}

.container{
    height: 1000px;
    width: 90%;
    margin: 0 auto;
}

#navbar{
    height: 50px;
    width: 100%;
    position: fixed;
    margin: 0 auto;
    background-color: #D35300;
}

#nav{
    background-color: #D35300;
    height: 50px;
}

I'm just looking to create a basic one of the LTT forum - no need for the toggle button to fade out or anything. This is my first post so I'm not 100% sure how to do stuff. Thanks in advance.

If you are allowed to use external JS or CSS libraries, then try the Affix plugin for bootstrap. (link: http://www.w3schools.com/bootstrap/bootstrap_affix.asp ). It makes what you are trying to accomplish simple.

If you are not allowed to use any external libraries then, I suggest you read this: http://getbootstrap.com/javascript/#affix-examples and try to implement it yourself.

Good Luck!

So I got it working with the following HTML, JS, and CSS files:

HTML

<html>
  <head>
    <link rel="stylesheet" href="path/to/font-awesome.css/file" type="text/css">
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <!-- Custom CSS File Below -->
    <link href="/path/to/custom/css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div class="topBanner">
      <img src="images/topbanner.png" id="topBannerimg"/>
    </div>
    <div id="navbar" data-spy="affix" data-offset-top="100">
      <button onclick="pinfunc()"><i id="pin" class="fa fa-thumb-tack fa-2x navButton" aria-hidden="true"></i></button>
    </div>

    <div id="SpaceFiller"></div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <script src="path/to/custom/js/file"></script>
  </body>
</html>

The key things to learn from this HTML are the loading the JS files at the bottom of the body tag so the page can load first, and the order in which the CSS and JS files are loaded. The SpacFiller div is just there to enable scrolling. Also, note that I removed your navbar-container as it didn't seem necessary.

Javascript

var pinned = true;

function pinfunc() {
   var  $pin = $("#pin");
   var  $navbar = $("#navbar");
   if (pinned) {
      $pin.css({
         'color': 'black',
         'transform': 'rotate(0deg)'
      });
      console.log("not pinned")
      $(window).off('.affix');
      $navbar.removeClass('affix affix-top affix-bottom');
      $navbar.removeData("bs.affix");
      pinned = false;
   } else {
      $pin.css({
         'color': 'red',
         'transform': 'rotate(270deg)'
      });
      $(window).on('.affix');
      $navbar.addClass('affix');
      $navbar.affix({
         offset: 100
      });
      pinned= true;
    }
}

This JS uses jQuery Selectors (which actually uses sizzle.js I believe) to get access to HTML elements via their IDs. Using the returned jQuery object, the function sets the appropriate CSS and then toggles affix using functions you can read about here: http://getbootstrap.com/javascript/#affix , https://api.jquery.com/removeclass/ , https://api.jquery.com/jQuery.removeData/ , http://api.jquery.com/off/ . Also, you were using 0 and 1 for the pinned values but it is good practice to use boolean values (true and false) as shown.

CSS

body{
   margin: 0 auto;
}

.affix {
   top: 0;
   width: 100%;
}

.affix + .container-fluid {
   padding-top: 70px;
}

#topBannerimg{
   width: 100%;
   margin: 0;
   display:block;
   height: 100px;
   top: 0px;
}

.navButton{
   height: 25px;
   width: 25px;
}

.fa-thumb-tack{
   font-size: 50px;
   color: red;
   transform: rotate(270deg);
}

#navbar{
   height: 50px;
   width: 100%;
   margin: 0 auto;
   background-color: #D35300;
}

#SpaceFiller {
  height: 10000px;
  background-color: darkgreen;
}

I think the CSS is self-explanatory, but if it is unclear go ahead and ask for clarification. Hope this helps! :D

Edit: You can also put the onclick attribute on the i tag itself and get rid of the button wrapper if you want to get rid of the white button background.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM