简体   繁体   English

如何使用Vanilla JavaScript在点击事件和新页面加载后滚动到元素

[英]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. 正如您将在代码中看到的那样,我试图利用CSS scroll-behaviour属性。 https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior 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 TypeError:无法读取未定义的属性“ offsetTop”

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. 因此,我推测window.onload函数并未真正在我要加载的页面上触发,而是在单击定位标记时位于同一页面上。 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. 您收到错误的原因是无法跨页面加载运行javascript。 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. 假设您使用的是传统网站,而不是单页应用,那么当浏览器加载新页面时,当前页面上的所有JavaScript都将停止。

Browsers already support jumping to an element on page load using the www.site.com#myElementId syntax. 浏览器已经支持使用www.site.com#myElementId语法跳转到页面加载时的元素。 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. 如果要平滑滚动,则需要传递element的id以在url中滚动,或采用其他方式(例如将其id缓存在localstorage中),然后在另一页的页面加载项上运行平滑滚动js。

You can't navigate to a different page and then ask the browser to launch a piece of JavaScript. 您无法导航到其他页面,然后要求浏览器启动一段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. 那将是一个巨大的安全问题,因为我可以让您单击一个链接,例如, my-bank.com,然后使用一些JavaScript来访问您的秘密Cookie或本地存储并入侵您的帐户。

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: 由于具有选项的.scrollTo JS方法具有与scroll-behavior CSS属性 相同的 浏览器兼容性 ,并且您对此表示满意,因此可以摆脱JS代码并进行设置:

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

and use anchor links. 并使用锚链接。

So HTML of Page A would be eg: 因此,页面A的HTML例如:

<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): 页面B的HTML(请注意<a name="#manufacturing">标记):

<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. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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