2

Here is a codepen which demonstrates my problem: http://codepen.io/PiotrBerebecki/pen/yaWQwZ

The objective is to have a scrolling animation when the user clicks on the

  1. Top navigation links, and
  2. Back to Top button in the bottom right corner.

I've managed to implement a vanilla JavaScript solution that meets requirement 1 but I'm struggling with requirement 2.

The solution relies on a recursive scrollTo function.

As you can see when you scroll down and click on the My work link, the animation runs correctly. However when you scroll down and click on the Back to Top button there is no animation and the page just jumps to top. I can't figure out why and how to fix it.

Here is the JS code:

(function() {


  // ======== SCROLL FUNCTION ======== //
  const scrollTo = (element, to, duration) => {
    if (duration <= 0) {return;}
    var difference = to - element.scrollTop;
    var perTick = difference / duration * 10;

    setTimeout(() => {
      element.scrollTop = element.scrollTop + perTick;
      if (element.scrollTop === to) {return;}
      scrollTo(element, to, duration - 10);
    }, 10);
  }


  // ======== TOP NAVIGATION ======== //
  // Save DOM elements that can be scrolled to
  let targetElements = {};
  (function() {
    const myWork = document.getElementById('my-work');
    const contact = document.getElementById('contact');
    targetElements = {
      'my-work': myWork,
      contact: contact
    };
  })();

  // Select links with scroll action
  const scrollElements = document.getElementsByClassName('scroll');

  // Add event listeners to navigation links with scroll action
  Array.prototype.forEach.call(scrollElements, scrollElement => {
    scrollElement.addEventListener('click', event => {
      event.preventDefault();
      const targetElement = targetElements[(scrollElement.getAttribute('href').slice(1))];
      scrollTo(document.body, targetElement.offsetTop, 800);
    });
  });


  // ======== BACK TO TOP BUTTON ======== // 
  const backToTopElement = document.getElementsByClassName('back-to-top')[0];
  const backToTopTargetElement = document.getElementById('my-work');

  backToTopElement.addEventListener('click', () => {
    scrollTo(document.body, backToTopTargetElement.offsetTop, 800);
  });

})();

Here is the HTML (the Back to Top button is at the bottom):

<!-- ======== NAVIGATION ======== -->
<nav role='navigation'>

  <div id="logo-container">
    <a class="scroll" href="#my-work">SUPER CAT</a>
  </div>

  <ul id="menu">
    <li><a class="scroll menu-link" href="#my-work">MY WORK</a></li>
    <li><a class="scroll menu-link" href="#contact">CONTACT</a></li>
  </ul>

</nav>


<!-- ======== MY WORK ======== -->
<article id="my-work">


  <header>
    <h1>MY WORK</h1>
  </header>


  ...


</article>


<!-- ======== CONTACT ======== -->
<footer id="contact">

  <h2>CONTACT</h2>

  ...

</footer>


<a href="#" class="back-to-top">Back to Top</a>
Piotr Berebecki
  • 7,428
  • 4
  • 33
  • 42

1 Answers1

3

Try removing the # anchor from the href in your <a> tag:

<a href="javascript:void(0);" class="back-to-top">Back to Top</a>

Updated pen: http://codepen.io/anon/pen/YGbBXz

Here's a great reference question/answer that should address any further questions about href="#" and the href property inclusion: What is href="#" and why is it used?

Summarizing the above post (in regards to question in the comments):

href="#" targets the top of the page.

href is required ONLY in the event the anchor tag is meant to be a hyperlink.

Community
  • 1
  • 1
roger
  • 1,091
  • 1
  • 7
  • 15
  • 2
    removing the href all together produces the same result – Jarod Moser Oct 28 '16 at 17:17
  • Why was the `#` anchor tag causing the issue? Also, is there any reason to use `"javascript:void(0);"` over just removing the `href`? – Piotr Berebecki Oct 28 '16 at 17:23
  • 1
    found a solid post (didn't want to reinvent the wheel here) which will hopefully be helpful in answering your further questions - see above edit – roger Oct 28 '16 at 17:36