0

I am using this template, and I would like to change URL when scrolling into sections.

I saw this answer, and I tried to update the code as shown below, but without success:

body {
  background-color: #ECECEC;
  color: #444444;
  padding: 0;
  margin: 0;
  perspective: 1px;
  transform-style: preserve-3d;
  height: 100%;
  overflow-x: hidden;
  font-family: 'Roboto';
}
.left-underline {
  display: inline-block;
  vertical-align: middle;
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  -moz-osx-font-smoothing: grayscale;
  position: relative;
  overflow: hidden;
}
.left-underline:before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  right: 100%;
  bottom: 0;
  background: #ECECEC;
  height: 4px;
  -webkit-transition-property: right;
  transition-property: right;
  -webkit-transition-duration: 0.15s;
  transition-duration: 0.15s;
  -webkit-transition-timing-function: ease-out;
  transition-timing-function: ease-out;
}
.left-underline:hover:before, .left-underline:focus:before, .left-underline:active:before {
  right: 0;
}
div.navbar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: #ee6e73;
  -webkit-box-shadow: 0px 2px 6px 0px rgba(50, 50, 50, 0.75);
  -moz-box-shadow:    0px 2px 6px 0px rgba(50, 50, 50, 0.75);
  box-shadow:         0px 2px 6px 0px rgba(50, 50, 50, 0.75);
  z-index: 9999999;
}
div.navbar > ul.navbar-container {
  list-style-type: none;
  margin: 0;
  padding-left: 1em;
  padding-right: 1em;
  overflow: hidden;
}
div.navbar > ul > li.nav-item {
  float: right;
  background-color: rgba(0, 0, 0, 0.1);
  transition: all 0.5s ease;
}
div.navbar > ul > li.active {
  background-color: rgba(0, 0, 0, 0.18);
}
div.navbar > ul > li:hover {
  background-color: rgba(0, 0, 0, 0.2);
}
a.nav-button {
  font-family: 'Roboto';
  text-decoration: none;
  line-height: 60px;
  padding-left: 20px;
  padding-right: 20px;
  color: rgba(228, 241, 254, 1);
  transition: all 0.5s ease;
}
a.nav-button:hover {
  text-decoration: none;
}
li.active > a.nav-button {
  cursor: default;
}
.brand-logo {
  float: left;
  cursor: default;
}
.parallax {
  height: 70vh;
  overflow: hidden;
  margin: 0;
  padding: 0;
}
.parallax.p1 {
  background: url(http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-70374.jpg) no-repeat fixed 50% 0;
  background-size: cover;
  color: #fff;
}
.parallax.p2 {
  background: url(http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-126549.jpg) no-repeat fixed 50% 0;
  background-size: cover;
  color: #fff;
}
.parallax.p3 {
  background: url(http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-95766.jpg) no-repeat fixed 70% 0;
  background-size: cover;
  color: #fff;
}
.parallax-text {
  width: 24em;
  position: fixed;
  top: 20%;
  left: 50%;
  border: .5em solid #fff;
  margin-left: -10%;
  padding: 2em 0;
  text-align: center;
  z-index: 999;
}
.parallax > div.blur-image {
  position: relative;
  width: 100%;
  height: 100%;
} 
hgroup{
  display: inline-block;
  text-align: center;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
  color: #fff;
  border: 5px solid #fff;
  padding: .5em 3em;
  background-color: rgba(0,0,0,.2);
  z-index: 2;
}
.row {
  width: 80%;
  padding-left: 10%;
  padding-right: 10%;
  padding-top: 15px;
  padding-bottom: 15px;
  min-height: 150px;
}
.row:after {
  content: "";
  display: table;
  clear: both;
}
.row > .col-3 {
  width: 30%;
  height: 100%;
  box-sizing: border-box;
  float: left;
  padding-left: 5px;
  padding-right: 5px;
}
footer {
  width: 100%;
  padding-top: 20px;
  display: block;
  background-color: #ee6e73;
}
.footer-copyright {
  font-weight: 300;
  overflow: hidden;
  height: 50px;
  line-height: 50px;
  color: rgba(255, 255, 255, 0.8);
  background-color: rgba(51, 51, 51, 0.08);
}
.container {
  width: 85%;
  padding: 0 1.5rem;
  margin: 0 auto;
  max-width: 1280px;
}
footer p {
  border-left: 3px solid #ffcdd2;
  padding-left: 15px;
  text-indent: 20px;
  color: #ececec;
}


/* Blank lines for ease and view */
/* */
<!doctype html>
<html>
  <head>
  <meta charset="utf-8">
  <title>Scrolling URL Hash</title>
  <meta name="description" content="Webpage for xxxx">

</head>

  <body> 
  <link href='template/style.css' rel='stylesheet' type='text/css'>
  <div class="navbar">
      <ul class="navbar-container">
        <li><a href="#" class="left-underline nav-button brand-logo">Brand Logo</a></li>
        <li class="nav-item"><a href="#section1" id="anchor1" class="left-underline nav-button brand-logo"><div>test2</a></li>
        <li class="nav-item"><a href="#section2" id="anchor2" class="left-underline nav-button brand-logo"><div>test</a></li>
        <li class="nav-item"><a href="#section3" id="anchor3" class="left-underline nav-button brand-logo"><div>try</a></li>
 
      </ul>
    </div>
    <div class="parallax p1" id="section1">
      <hgroup>
        <h1>Hello.</h1>
        <h2>I’m a startup.</h2>
      </hgroup>
    </div>
    <div class="row">
      <div class="col-3">
        <h1>First Section Col1</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam cursus maximus quam et dignissim. Praesent felis arcu, euismod et ullamcorper ut, condimentum ut ante. Vestibulum vel libero commodo, aliquam libero </p>
      </div>
      <div class="col-3">
        <h1>First Section Col2</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque imperdiet est id leo facilisis, quis egestas erat vehicula.</p>
      </div>
      <div class="col-3">
        <h1>First Section Col3</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ac nibh dolor. Cras rutrum molestie ligula posuere hendrerit. </p>
      </div>
    </div>

    <div class="parallax p2" id="section2">
      <hgroup>
        <h1>tshdgjdfjsthstr</h1>
        <h2>I’m a startup.</h2>
      </hgroup>
    </div>
    <div class="row">
      <div class="col-3">
        <h1>First Section Col1</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam cursus maximus quam et dignissim. Praesent felis arcu, euismod et ullamcorper ut, condimentum ut ante. Vestibulum vel libero commodo, aliquam libero </p>
      </div>
      <div class="col-3">
        <h1>First Section Col2</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque imperdiet est id leo facilisis, quis egestas erat vehicula.</p>
      </div>
      <div class="col-3">
        <h1>First Section Col3</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ac nibh dolor. Cras rutrum molestie ligula posuere hendrerit. </p>
      </div>
    </div>
  <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
  <script>
    // stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
    function isElementInViewport (el) {
      //special bonus for those using jQuery
      if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
      }
      var rect = el.getBoundingClientRect();
      return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
      );
    }
    // click-to-scroll behavior
    $(".left-underline nav-button brand-logo").click(function (e) {
      e.preventDefault();
      var section = this.href;
      var sectionClean = section.substring(section.indexOf("#"));
      $("html, body").animate({
        scrollTop: $(sectionClean).offset().top
      }, 1000, function () {
        window.location.hash = sectionClean;
      });
    });
    // listen for the scroll event
    $(document).on("scroll", function() {
      console.log("onscroll event fired...");
      // check if the anchor elements are visible
      $("..left-underline nav-button brand-logo").each(function (idx, el) {
        if ( isElementInViewport(el) ) {
          // update the URL hash
          if (window.history.pushState) {
            var urlHash = "#" + $(el).attr("href");
            window.history.pushState(null, null, urlHash);
          }
        }
      });
    });
  </script>
  </body>
</html>

How can I solve the problem? Thanks

PS. I have also seen that not always the navbar stays on top, why does it happen?

Joe
  • 12,057
  • 5
  • 39
  • 55

1 Answers1

1

You have a syntax error on this line : $("..left-underline nav-button brand-logo").each(function (idx, el) { There should only be one dot, giving something like this : $(".left-underline nav-button brand-logo").each(function (idx, el) {

The error disappears from the console.

body {
  background-color: #ECECEC;
  color: #444444;
  padding: 0;
  margin: 0;
  perspective: 1px;
  transform-style: preserve-3d;
  height: 100%;
  overflow-x: hidden;
  font-family: 'Roboto';
}
.left-underline {
  display: inline-block;
  vertical-align: middle;
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  box-shadow: 0 0 1px rgba(0, 0, 0, 0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  -moz-osx-font-smoothing: grayscale;
  position: relative;
  overflow: hidden;
}
.left-underline:before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  right: 100%;
  bottom: 0;
  background: #ECECEC;
  height: 4px;
  -webkit-transition-property: right;
  transition-property: right;
  -webkit-transition-duration: 0.15s;
  transition-duration: 0.15s;
  -webkit-transition-timing-function: ease-out;
  transition-timing-function: ease-out;
}
.left-underline:hover:before, .left-underline:focus:before, .left-underline:active:before {
  right: 0;
}
div.navbar {
  position: sticky;
  top: 0;
  left: 0;
  width: 100%;
  background: #ee6e73;
  -webkit-box-shadow: 0px 2px 6px 0px rgba(50, 50, 50, 0.75);
  -moz-box-shadow:    0px 2px 6px 0px rgba(50, 50, 50, 0.75);
  box-shadow:         0px 2px 6px 0px rgba(50, 50, 50, 0.75);
  z-index: 9999999;
}
div.navbar > ul.navbar-container {
  list-style-type: none;
  margin: 0;
  padding-left: 1em;
  padding-right: 1em;
  overflow: hidden;
}
div.navbar > ul > li.nav-item {
  float: right;
  background-color: rgba(0, 0, 0, 0.1);
  transition: all 0.5s ease;
}
div.navbar > ul > li.active {
  background-color: rgba(0, 0, 0, 0.18);
}
div.navbar > ul > li:hover {
  background-color: rgba(0, 0, 0, 0.2);
}
a.nav-button {
  font-family: 'Roboto';
  text-decoration: none;
  line-height: 60px;
  padding-left: 20px;
  padding-right: 20px;
  color: rgba(228, 241, 254, 1);
  transition: all 0.5s ease;
}
a.nav-button:hover {
  text-decoration: none;
}
li.active > a.nav-button {
  cursor: default;
}
.brand-logo {
  float: left;
  cursor: default;
}
.parallax {
  height: 70vh;
  overflow: hidden;
  margin: 0;
  padding: 0;
}
.parallax.p1 {
  background: url(http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-70374.jpg) no-repeat fixed 50% 0;
  background-size: cover;
  color: #fff;
}
.parallax.p2 {
  background: url(http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-126549.jpg) no-repeat fixed 50% 0;
  background-size: cover;
  color: #fff;
}
.parallax.p3 {
  background: url(http://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-95766.jpg) no-repeat fixed 70% 0;
  background-size: cover;
  color: #fff;
}
.parallax-text {
  width: 24em;
  position: fixed;
  top: 20%;
  left: 50%;
  border: .5em solid #fff;
  margin-left: -10%;
  padding: 2em 0;
  text-align: center;
  z-index: 999;
}
.parallax > div.blur-image {
  position: relative;
  width: 100%;
  height: 100%;
} 
hgroup{
  display: inline-block;
  text-align: center;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
  color: #fff;
  border: 5px solid #fff;
  padding: .5em 3em;
  background-color: rgba(0,0,0,.2);
  z-index: 2;
}
.row {
  width: 80%;
  padding-left: 10%;
  padding-right: 10%;
  padding-top: 15px;
  padding-bottom: 15px;
  min-height: 150px;
}
.row:after {
  content: "";
  display: table;
  clear: both;
}
.row > .col-3 {
  width: 30%;
  height: 100%;
  box-sizing: border-box;
  float: left;
  padding-left: 5px;
  padding-right: 5px;
}
footer {
  width: 100%;
  padding-top: 20px;
  display: block;
  background-color: #ee6e73;
}
.footer-copyright {
  font-weight: 300;
  overflow: hidden;
  height: 50px;
  line-height: 50px;
  color: rgba(255, 255, 255, 0.8);
  background-color: rgba(51, 51, 51, 0.08);
}
.container {
  width: 85%;
  padding: 0 1.5rem;
  margin: 0 auto;
  max-width: 1280px;
}
footer p {
  border-left: 3px solid #ffcdd2;
  padding-left: 15px;
  text-indent: 20px;
  color: #ececec;
}


/* Blank lines for ease and view */
/* */
<!doctype html>
<html>
  <head>
  <meta charset="utf-8">
  <title>Scrolling URL Hash</title>
  <meta name="description" content="Webpage for xxxx">
  <link rel="stylesheet" href="style.css">

</head>

  <body> 
  <link href='template/style.css' rel='stylesheet' type='text/css'>
  <div class="navbar">
      <ul class="navbar-container">
        <li><a href="#" class="left-underline nav-button brand-logo">Brand Logo</a></li>
        <li class="nav-item"><a href="#section1" id="anchor1" class="left-underline nav-button brand-logo"><div>test2</a></li>
        <li class="nav-item"><a href="#section2" id="anchor2" class="left-underline nav-button brand-logo"><div>test</a></li>
        <li class="nav-item"><a href="#section3" id="anchor3" class="left-underline nav-button brand-logo"><div>try</a></li>
 
      </ul>
    </div>
    <div class="parallax p1" id="section1">
      <hgroup>
        <h1>Hello.</h1>
        <h2>I’m a startup.</h2>
      </hgroup>
    </div>
    <div class="row">
      <div class="col-3">
        <h1>First Section Col1</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam cursus maximus quam et dignissim. Praesent felis arcu, euismod et ullamcorper ut, condimentum ut ante. Vestibulum vel libero commodo, aliquam libero </p>
      </div>
      <div class="col-3">
        <h1>First Section Col2</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque imperdiet est id leo facilisis, quis egestas erat vehicula.</p>
      </div>
      <div class="col-3">
        <h1>First Section Col3</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ac nibh dolor. Cras rutrum molestie ligula posuere hendrerit. </p>
      </div>
    </div>

    <div class="parallax p2" id="section2">
      <hgroup>
        <h1>tshdgjdfjsthstr</h1>
        <h2>I’m a startup.</h2>
      </hgroup>
    </div>
    <div class="row">
      <div class="col-3">
        <h1>First Section Col1</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam cursus maximus quam et dignissim. Praesent felis arcu, euismod et ullamcorper ut, condimentum ut ante. Vestibulum vel libero commodo, aliquam libero </p>
      </div>
      <div class="col-3">
        <h1>First Section Col2</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque imperdiet est id leo facilisis, quis egestas erat vehicula.</p>
      </div>
      <div class="col-3">
        <h1>First Section Col3</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ac nibh dolor. Cras rutrum molestie ligula posuere hendrerit. </p>
      </div>
    </div>
  <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
  <script>
    // stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
    function isElementInViewport (el) {
      //special bonus for those using jQuery
      if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
      }
      var rect = el.getBoundingClientRect();
      return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
      );
    }
    // click-to-scroll behavior
    $(".left-underline, .nav-button, .brand-logo").click(function (e) {
      e.preventDefault();
      var section = this.href;
      var sectionClean = section.substring(section.indexOf("#"));
      $("html, body").animate({
        scrollTop: $(sectionClean).offset().top
      }, 1000, function () {
        window.location.hash = sectionClean;
      });
    });

    // listen for the scroll event
    $(document).on("scroll", function() {
      // check if the anchor elements are visible
      $("#section1, #section2").each(function (idx, el) {
        console.log(el)
        if ( isElementInViewport(el) ) {
          // update the URL hash
          if (window.history.pushState) {
            var urlHash = "#" + $(el).attr("id");
            window.history.pushState(null, null, urlHash);
          }
        }
      });
    });
  </script>
  </body>
</html>
Baptiste
  • 68
  • 1
  • 10
  • Thanks Baptiste, that was an error, but still I dont see the URL updating when scrolling – Joe Mar 31 '21 at 11:46
  • 1
    I tested your script, and I found errors on this line : $(".left-underline nav-button brand-logo"). As left-underline, nav-button etc.. are different classes, you should use $(".left-underline, .nav-button, .brand-logo"). For the moment, as it was, the script wasn't running the .each(function()), as well as the click() function. Jquery doesn't recognize this selector – Baptiste Mar 31 '21 at 12:07
  • Thanks Baptiste, it works for what I have to do so I accepted the answer. So when I go from bottom to top it "resets" the URL (only) to the header section, but when I scroll down it doesnt. Any clue why? Also do you know why the navbar doesnt stick to the top? Thanks for your help, much appreciated – Joe Mar 31 '21 at 17:24
  • Also I have noticed that this line var urlHash = "#" + $(el).attr("href"); should have been: var urlHash = $(el).attr("href"); – Joe Mar 31 '21 at 17:29
  • Hi Joe, I don't really have a clue on why it doesn't reset the URL on scrolling down but I am currently looking at it. For the navbar, after doing some testing, I realized that it's not `position: fixed;` but `position: sticky;` and it does make the navbar stick to the top ! – Baptiste Mar 31 '21 at 17:32
  • Sticky indeed works on the link I shared in the question and in the test code I used for the question, but not when I try on my bigger program (it includes also Flask) in Chrome. It also seems that Sticky doesnt work properly with the URL. Do you experience the same? Thanks for your help – Joe Mar 31 '21 at 17:46
  • I think I made it work, could you test my answer (which I'm going to edit right now) and tell me if this fits you ? If you want the URL to change based on the section present on screen, you want to iterate through the section elements and not the buttons id (I put the sections id as selectors, but I guess it would work fine with the class). For the sticky part, it's working well for me, so it might not be working because of something else present in your "bigger program" css code – Baptiste Mar 31 '21 at 18:29
  • Yes, now it works good, thanks. The only thing is still that I cannot sticky the navbar.even using the same css. Maybe I have to adjust the HTML – Joe Mar 31 '21 at 19:13