1

I have a simple page where I am going to place a large form on the right side, and a navigation menu on the left allowing the user to jump to sections of the large form (this could also be used for large articles too - for now to mock the size I have added a large bottom padding with CSS). The right column has been styled to fit the height of the window using height: 100vh Here is a JsBin example: https://jsbin.com/keniriz/edit?html,css,js,console,output

Where I will put the form I have put some anchors and I have created a Javascript function to scroll the form to where desired. This is my HTML...

  <div class="aims-form">
  <div class="aims-form__navigation">
    <ul>
      <li>
        <a onClick="scrollToAchor('section1')" class="aims-form__anchor">Section 1</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section2')" class="aims-form__anchor">Section 2</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section3')" class="aims-form__anchor">Section 3</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section4')" class="aims-form__anchor">Section 4</a>
      </li>
    </ul>
  </div>
  <div class="aims-form__form">
    <section>
      Section 1<a name="section1"></a>
      <br>
      Content coming soon...
    </section>
    <section>
      Section 2<a name="section2"></a>
      <br>
      Content coming soon..
    </section>
    <section>
      Section 3<a name="section3"></a>
      <br>
      Content coming soon..
    </section>
    <section>
      Section 4<a name="section4"></a>
      <br>
      Content coming soon..
    </section>
  </div>
</div>

Now when I click on one of the links on the left I wish the appropriate section to scroll to the top of the <div class="aims-form__form"> however I have noticed that this doesn't happen! Sometimes it seems to just bring into into view and also the page seems to jump to top so the <div class="aims-form__form"> to the top of the browser window... I don't want this to happen. Obviously something is wrong with my implementation, here is the Javascript:

function scrollToAchor(where) {
  var element = document.querySelector('.aims-form__form').querySelector('a[name="' + where + '"]');
  element.scrollIntoView({ behavior: 'smooth' });
}

Can anyone tell me how I can overcome the issue of the page jumping to the top and how I can bring the scrollable section to the top of the page? Any advice is appreciated.

Once again, here is a jsbin of the full thing (with necessary css) https://jsbin.com/keniriz/edit?html,css,js,console,output

Mike Sav
  • 14,805
  • 31
  • 98
  • 143

1 Answers1

2

You don't need to use scrollIntoView if you are working with links. You can just give the anchor tags a href of # plus the name attribute of the link you want to scroll to.

<a href="#section">Section</a>
<!--Will scroll to:-->
<a name="section">Section!!!</a>

  <div class="aims-form">
  <div class="aims-form__navigation">
    <ul>
      <li>
        <a href='#section1' class="aims-form__anchor">Section 1</a>
      </li>
      <li>
        <a href='#section2' class="aims-form__anchor">Section 2</a>
      </li>
      <li>
        <a href='#section3' class="aims-form__anchor">Section 3</a>
      </li>
      <li>
        <a href='#section4' class="aims-form__anchor">Section 4</a>
      </li>
    </ul>
  </div>
  <div style="margin-top: 300px;"></div>
  <div class="aims-form__form">
    <section style="margin: 200px;">
      Section 1<a name="section1"></a>
      <br>
      Content coming soon...
    </section>
    <section style="margin: 200px;">
      Section 2<a name="section2"></a>
      <br>
      Content coming soon..
    </section>
    <section style="margin: 200px;">
      Section 3<a name="section3"></a>
      <br>
      Content coming soon..
    </section>
    <section style="margin: 200px;">
      Section 4<a name="section4"></a>
      <br>
      Content coming soon..
    </section>
  </div>
</div>
<script>
</script>

You can also use window.scrollTo(0, element.offsetTop) to scroll to the element's exact position with Javascript (the element will be positioned right at the top of the viewport).

 <html>
 <head>
 <style>
 section{
    margin: 200px;
 }
 </style>
 </head>
 <body>
 <div class="aims-form">
  <div class="aims-form__navigation">
    <ul>
      <li>
        <a onClick="scrollToAchor('section1')" class="aims-form__anchor">Section 1</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section2')" class="aims-form__anchor">Section 2</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section3')" class="aims-form__anchor">Section 3</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section4')" class="aims-form__anchor">Section 4</a>
      </li>
    </ul>
  </div>
  <div class="aims-form__form">
    <section>
      Section 1<a name="section1"></a>
      <br>
      Content coming soon...
    </section>
    <section>
      Section 2<a name="section2"></a>
      <br>
      Content coming soon..
    </section>
    <section>
      Section 3<a name="section3"></a>
      <br>
      Content coming soon..
    </section>
    <section>
      Section 4<a name="section4"></a>
      <br>
      Content coming soon..
    </section>
  </div>
</div>
<div style="margin-bottom: 500px;"></div>
<script>
function scrollToAchor(where) {
  var element = document.querySelector('.aims-form__form').querySelector('a[name="' + where + '"]');
  window.scrollTo(0, element.offsetTop);
}
</script>
</body>
</html>

For smooth scrolling, you can use a for loop using window.scrollTo and setTimeout to scroll slowly.

 <html>
 <head>
 <style>
 section{
    margin: 200px;
 }
 </style>
 </head>
 <body>
 <div class="aims-form">
  <div class="aims-form__navigation">
    <ul>
      <li>
        <a onClick="scrollToAchor('section1')" class="aims-form__anchor">Section 1</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section2')" class="aims-form__anchor">Section 2</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section3')" class="aims-form__anchor">Section 3</a>
      </li>
      <li>
        <a onClick="scrollToAchor('section4')" class="aims-form__anchor">Section 4</a>
      </li>
    </ul>
  </div>
  <div class="aims-form__form">
    <section>
      Section 1<a name="section1"></a>
      <br>
      Content coming soon...
    </section>
    <section>
      Section 2<a name="section2"></a>
      <br>
      Content coming soon..
    </section>
    <section>
      Section 3<a name="section3"></a>
      <br>
      Content coming soon..
    </section>
    <section>
      Section 4<a name="section4"></a>
      <br>
      Content coming soon..
    </section>
  </div>
</div>
<div style="margin-bottom: 500px;"></div>
<script>
function scrollToAchor(where) {
  var element = document.querySelector('.aims-form__form').querySelector('a[name="' + where + '"]');
  var position = element.offsetTop;
  for(let i = 10; i <= position; i+=10){
    setTimeout(function(){
    window.scrollTo(0, i);
    }, i/2);
  }
}
</script>
</body>
</html>

For a more comprehensive list of methods for smooth scrolling, see my answer here.

Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • Thanks, I've ammended my code and now have it working (bit not 100% - I need to ask another question). I can't use anchors due to the layout of the page and it's also an Angular app I am writing... thanks for the help anyway. – Mike Sav Aug 05 '18 at 10:34
  • @MikeSav Just use any other tag combined with the Javascript in my third code snippet. – Unmitigated Aug 05 '18 at 13:50