【问题标题】:Problem while trying to scroll window to an element position using intersectionObserver尝试使用 intersectionObserver 将窗口滚动到元素位置时出现问题
【发布时间】:2020-03-05 22:44:25
【问题描述】:

我正在尝试使用intersectionObserver 制作幻灯片网站。基本上,我 grep 元素并监听相交事件,然后我想将 window.srollTo 设置为元素的 offsetTop。我试过window.scrollTo(0, 10)、elem.scrollIntoView()、window.scrollBy(),但没有任何效果。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      body,
      html {
        position: ablolute;
        -ms-overflow-style: none;
        display: block;
        height: 100vh;
        width: 100%;
      }
      body::-webkit-scrollbar {
        width: 0 !important;
      }

      .page {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div class="page">one</div>
    <div class="page">two</div>
    <div class="page">three</div>
    <div class="page">four</div>
    <script>

      const pages = document.querySelectorAll('.page');
      const observer = new IntersectionObserver(
        entries => {
          entries.forEach(entry => {
            if (entry.isIntersecting == true) {

              console.log(entry.target.offsetTop);
              entry.target.scrollIntoView(top);
            }
          });
        },
        {threshold: 0.01},
      );
      pages.forEach(page => {
        observer.observe(page);
      });
    </script>
  </body>
</html>

【问题讨论】:

  • entry.target.scrollIntoView(top);top从何而来?
  • 嗨,Maksym,请您编辑帖子的标题。不清楚您的问题是什么。

标签: javascript ecmascript-5 intersection-observer


【解决方案1】:

首先scrollIntoView 采用Boolean 或选项Object。我不知道top 应该是什么,因为它不在您的代码中,但它不正确。

您的滚动事件不断触发并覆盖您的scrollIntoView。为了停止这种情况,您可以设置容器的 overflow 属性,使其不再允许滚动,禁用事件,然后在调用 scrollIntoView 之前使用计时器重新启用它。

          entries.forEach(entry => {
        if (entry.isIntersecting == true) {

          console.log(entry.target.offsetTop);
          document.body.setAttribute('style','overflow:hidden;');

          setTimeout(function(){
           document.body.setAttribute('style','overflow:visible;');       
           entry.target.scrollIntoView(true);
           }, 250);

        }

例子:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      body,
      html {
        position: absolute;
        -ms-overflow-style: none;
        display: block;
        height: 100vh;
        width: 100%;
      }
      body::-webkit-scrollbar {
        width: 0 !important;
      }

      .page {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div class="page">one</div>
    <div class="page">two</div>
    <div class="page">three</div>
    <div class="page">four</div>
    <script>
      const pages = document.querySelectorAll('.page');
      const observer = new IntersectionObserver(
        entries => {
          entries.forEach(entry => {
            if (entry.isIntersecting == true) {

              console.log(entry.target.offsetTop);
              document.body.setAttribute('style','overflow:hidden;');

              setTimeout(function(){
               document.body.setAttribute('style','overflow:visible;');       
               entry.target.scrollIntoView(true);
               }, 250);
        
            }
          });
        },
        {threshold: 0.10},
      );
      pages.forEach(page => {
        observer.observe(page);
      });
    </script>
  </body>
</html>

注意可能有更好的方法可以在没有计时器的情况下执行此操作 - 例如闭包中的标志等,但这应该让您了解导致问题的原因以及如何解决它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    相关资源
    最近更新 更多