简体   繁体   中英

How to scroll to element after click event and new page load with Vanilla JavaScript

I will try to summarize this in a Requirements fashioned way, I hope this simplifies the question.

When clicking on an anchor tag, the web page navigates the user to a new page, where upon page load, the page is scrolled to the element which corresponds to the aforementioned anchor tag, which was previously clicked.

As you will see in the code I am trying to make use of the CSS scroll-behaviour property. https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior

So far I have tried out the code bellow, however when I run it I get an error message in the developer console stating:

TypeError: Cannot read property 'offsetTop' of undefined

Hence, I surmise that the window.onload function is not really fired on the page which I would like to load but the very same page on which I am located when clicking the anchor tag. How can I change the code so it would count for page intended.

HTML of Page A (where the anchor tag is located):

   <a id="ship-it" href="services.html" class="services">
    <div id="image-container_4">
      <div id="image_4">
        <div id="overlay_4"></div>
        <h2 class="h2">We pack it and ship it</h2>
        <img id=imageB src="/images/shipping.jpg" alt="">
      </div>
    </div>
  </a>

HTML of Page B (where the target element is located):
<section id="manufacturing-section" class="section">

    <img src="/images/manufacturingMelting2.jpg" alt="Magnetic Particle Inspection">

    <div id="manufacturing-container">
      <h2> <span>Manufacturing</span> <br> We provide high quality, low cost solutions to meet your requirements.</h2>

      <p>
        soemthing something something, DarkSide...
      </p>

    </div>

  </section>

JS / CSS:

function scrollIt(element) {
  window.scrollTo({
    'behavior': 'smooth',
    'left': 0,
    'top': element.offsetTop
  });
}


const serviceAnchor = document.querySelectorAll('.services');
//'serviceAnchor' is located on page A
const sections = document.querySelectorAll('.section');
// 'sections' is located on page B and represents the element the page should scroll to when the page has loaded after the corresponding anchor tag was clicked


serviceAnchor[0].addEventListener('click', () =>  {
  window.onload = scrollIt(sections[0]);
});

serviceAnchor[1].addEventListener('click', () =>  {
  window.onload = scrollIt(sections[1]);
 });

 serviceAnchor[2].addEventListener('click', () =>  {
  window.onload = scrollIt(sections[2]);
 });

 serviceAnchor[3].addEventListener('click', () =>  {
  window.onload = scrollIt(sections[3]);
 });

The reason you're getting the error is it's impossible to run javascript across page loads. Assuming you're using a traditional site and not a single-page app, when the browser loads a new page, all javascript on the current page is stopped.

Browsers already support jumping to an element on page load using the www.site.com#myElementId syntax. If you want smooth scrolling, you'll need to pass the id of element to scroll in the url, or some other way like caching its id in localstorage, then run your smooth scrolling js on the pageload of the other page.

You can't navigate to a different page and then ask the browser to launch a piece of JavaScript. That would be a huge security issue, since I could make you click into a link to, let's say, my-bank.com then do a bit of JavaScript do access your secret cookies or local storage and hack into your account.

The only thing you can do is link to anchors inside the linked page, and the default scroll behavior (no smooth scrolling, for most browsers, since it's the least computationally and resources intensive) will be used:

<!-- not possible -->
<a onclick="navigateThenDoSomething()">Some link</a>
<!-- possible -->
<a href="some-url#some-section">Some link</a>

If you own the target page, however, you can hide a target section in the query string then do a bit of magic in the target page's onload to smoothly scroll to your section:

<!-- source-page.html -->
<a href="target-page?section=some-section">Some link</a>
// script running at target-page.html
const url = new URL(window.location);
const section = url.searchParams.get('section');
if (section) {
  // scroll smoothly to `section` using
}

Since .scrollTo JS method with options has the same browser compatibility as scroll-behavior CSS property , and you're OK with that, you might get rid of your JS code and set:

html, body, .or-other-scrolling-container {scroll-behavior:smooth}

and use anchor links.

So HTML of Page A would be eg:

<a id="ship-it" href="services.html#manufacturing" class="services">
  <div id="image-container_4">
    <div id="image_4">
      <div id="overlay_4"></div>
      <h2 class="h2">We pack it and ship it</h2>
      <img id=imageB src="/images/shipping.jpg" alt="">
    </div>
  </div>
</a>

And HTML of Page B (please note <a name="#manufacturing"> tag):

<a name="manufacturing"></a>
<section id="manufacturing-section" class="section">
  <img src="/images/manufacturingMelting2.jpg" alt="Magnetic Particle Inspection">
  <div id="manufacturing-container">
    <h2>
      <span>Manufacturing</span><br>
      We provide high quality, low cost solutions to meet your requirements.
    </h2>
    <p>something something something, DarkSide...</p>
  </div>
</section>

Working example:

 html {scroll-behavior:smooth} .long {height:100vh; background:#efc} 
 <a id="ship-it" href="#manufacturing" class="services"> <div id="image-container_4"> <div id="image_4"> <div id="overlay_4"></div> <h2 class="h2">We pack it and ship it</h2> <img id=imageB src="https://picsum.photos/50/50" alt=""> </div> </div> </a> <section class="long">Placeholder to enable scroll</section> <a name="manufacturing"></a> <section id="manufacturing-section" class="section"> <img src="https://picsum.photos/400/220" alt="Magnetic Particle Inspection"> <div id="manufacturing-container"> <h2> <span>Manufacturing</span><br> We provide high quality, low cost solutions to meet your requirements. </h2> <p>something something something, DarkSide...</p> </div> </section> 

Hope it helps.

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