javascript - 滚动位置> 0后如何平滑向下滚动到元素?

标签 javascript

我的页面顶部有一个全屏预告片。当用户开始滚动时,我希望整个页面自动顺畅地向下滚动到下一段。

不幸的是,下面的代码不起作用。正如发布的那样,它根本不滚动,当我不将滚动变量设置为 true 以避免多次执行 scrollIntoView 时,它非常慢。

使用 vanilla JS 解决这个问题的好方法是什么?

示例,在 Chrome 中测试:

let scrolling = false;

window.onscroll = () => {
  const offset = window.pageYOffset;
  if (offset > 0 && offset < window.innerWidth && !scrolling) {
    scrolling = true;
    document.querySelector('.somecontent').scrollIntoView({behavior:'smooth'});
  }
  
  if (offset >= window.innerWidth) {
    scrolling = false;
  }
}
.someteaser {
  background: blue;
  height: 100vh;
  width: 100vw;
}

.somecontent {
  background: red;
  height: 200vh;
  width: 100vw;
}
<div class="someteaser"></div>
<div class="somecontent"></div>

//更新

所以问题是 behavior:'smooth' 选项。没有它,滚动会起作用,但当然不再流畅了。这似乎是 scorllIntoView 上的一个错误,我不太明白。我的临时解决方案使用这个脚本,它工作正常:https://github.com/cferdinandi/smooth-scroll

最佳答案

我对这个问题很感兴趣,所以我这样做了,试图让它变宽(它可以自动上下滚动)。我希望它适合你的问题..

(片段在整页上效果更好)

const
  AllSections   = document.querySelectorAll('body > section'), // all target Section reference
  SectionsCount = AllSections.length,
  opt           = {behavior: "smooth", block: "start"};

var
  NoSmooth       = true, // autoScroll is off
  Last_W_PosY    = 0,    // used to determine scrolling event direction
  Smooth_Id      = 0,    // setTimeout for launching autoScroll
  Smooth_End     = 0,    // setinterval to detect end of autoScroll
  Scroll2Section = -1;   // target section for autoScroll

window.onscroll = () => {
  clearTimeout(Smooth_Id);
  let
    W_PosY    = window.pageYOffset,
    W_height  = window.innerHeight,
    direction = (Last_W_PosY < W_PosY) ? 'down' : 'up';

  if (NoSmooth){
    Scroll2Section = -1;
    let parts_Section = true;

    for(let i = 0; i< SectionsCount; i++){
      let SectionRect = AllSections[i].getBoundingClientRect();
      if ( SectionRect.y <= 0 && (SectionRect.height + SectionRect.y) >= W_height )
      {
        parts_Section = false;
        break;
      }
    }
    if (parts_Section){
      if (direction==='down') {
        for (let i = 0; i< SectionsCount; i++){
          if (AllSections[i].getBoundingClientRect().y > 0 ) {
            Scroll2Section = i;
            break;
          }
        }
      }
      if (direction==='up') {
        for (let i = SectionsCount; i-->0;){
          if (AllSections[i].getBoundingClientRect().y < 1) { // somme top position are not precise
            Scroll2Section = i;
            break;
          }
        }
      }
    }

    if (parts_Section) {
      Smooth_Id = setTimeout(Smooth_Action, 300) // reaction delay for auto scroll
    }
  }
  Last_W_PosY = W_PosY;
}

function Smooth_Action(){
  NoSmooth = false;
  AllSections[Scroll2Section].scrollIntoView( opt );
  clearInterval(Smooth_End);
  Smooth_End = setInterval(Wait_Smooth_Finish, 100 )
}

function Wait_Smooth_Finish(){
  let W_PosY = window.pageYOffset;
  if (Last_W_PosY==W_PosY) {
    NoSmooth = true;
    clearInterval(Smooth_End);
  }
  Last_W_PosY = W_PosY;
}
body           { margin: 0; }
body > section { display: block; width: 100%; margin: 0  }
.content_0     { height: 100vh; background: #001f3f; }
.content_1     { height: 120vh; background: #FF851B; }
.content_2     { height: 140vh; background: #39CCCC; }
.content_3     { height: 160vh; background: #F012BE; }
p { display:inline-block; margin:20px; padding:3px; background-color:#f0f8ff }
<section class="content_0"> <p>1 / 4</p> </section>
<section class="content_1"> <p>2 / 4</p> </section>
<section class="content_2"> <p>3 / 4</p> </section>
<section class="content_3"> <p>4 / 4</p> </section>

关于javascript - 滚动位置> 0后如何平滑向下滚动到元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56079729/

相关文章:

javascript - 从对象生成的 AngularJS 选择框

javascript - 如何利用 Intellisense 将 js 库导入 Typescript 模块/VS Code 任务

javascript - Ajax PHP 表单提交(包含图像和文本)

javascript - 弹出窗口在一个浏览器上工作,但在另一个浏览器上不工作

php - 在 javascript 生成的页面上将 javascript 变量传递给 php

javascript - 数据表排序但对行进行分组

javascript - Node 中的基本 html 引擎

javascript - ng-repeat 渲染并自动滚动到底部

javascript - 从 javascript 访问 mvc modelstate 属性,数组属性名为 ""

javascript - 旋转期间 HTML 元素呈现不佳