在给定的时间后,平滑滚动到当前部分的中心 [英] Smooth Scroll to center current section after a given amount of time

查看:75
本文介绍了在给定的时间后,平滑滚动到当前部分的中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个页面导航站点,所有部分/导航元素的min-height都设置为100vh.有了这个,我就可以轻松浏览滚动条了.

如果我手动滚动并且该部分未居中(就像单击菜单项一样),我希望它在给定的时间后居中.请注意,我不想禁用滚动功能以仅通过菜单进行导航.

我正在考虑将某些与smoothscroll代码一起添加的js.可以检查截面位置偏移的东西,如果它没有居中,则可以使用一些缓动功能使其平滑滚动.

https://jsfiddle.net/9ta3yh52/以此为参考,如果颜色是在视口的75%以上,滚动到该元素.

感谢您的帮助:)

编辑/解决方案:

到目前为止,@ Hastig Zusammenstellen给出了最接近的方法

https://stackoverflow.com/a/39188110/6717849

您必须根据需要对其进行修改,以匹配您拥有的部分的数量.将节设置为height: 100vh时,逻辑很简单:

if (scrollTop <= sectionHeightHalf) {
    $('html, body').animate({
      scrollTop: $("#section1").offset().top
    }, 300);
  } else if (scrollTop >= sectionHeightHalf && scrollTop <= ($(window).height() * 2 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#section2").offset().top
      }, 300);
  } else if (scrollTop >= sectionHeightHalf && scrollTop <= ($(window).height() * 3 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#section3").offset().top
      }, 300);
  } else if (scrollTop >= sectionHeightHalf && scrollTop <= ($(window).height() * 4 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#section4").offset().top
      }, 300);
  } else if (scrollTop >= sectionHeightHalf && scrollTop <= ($(window).height() * 5 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#section5").offset().top
      }, 300);

// etc etc

  } else if (scrollTop >= ($(window).height() * 2 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#lastsection").offset().top
      }, 300);
  }

解决方案

新版本使用从这里.

它修复了上一个版本中的双滚动问题,但现在似乎在自动居中之后有时仍然停留.

 $(function() {
  $(window).scroll(function() {
    $('monitor').html('SCROLLING');
    clearTimeout($.data(this, 'scrollCheck'));
    $.data(this, 'scrollCheck', setTimeout(function() {
      $('monitor').html('PAUSED');
      var sectionHeightHalf = $(window).height() / 2;
      var scrollTop = $(window).scrollTop();
      if (scrollTop <= sectionHeightHalf) {
        $('html, body').animate({
          scrollTop: $("#about").offset().top
        }, 300);
      } else if 
        (scrollTop >= sectionHeightHalf && 
         scrollTop <= ($(window).height() * 2 - sectionHeightHalf)) {
          $('html, body').animate({
            scrollTop: $("#services").offset().top
          }, 300);
        } else if (scrollTop >= ($(window).height() * 2 - sectionHeightHalf)) {
          $('html, body').animate({
            scrollTop: $("#gallery").offset().top
          }, 300);
        }
    }, 300) );
  });
}); 

 html, body {
  margin: 0;
  padding: 0;
}
section {
  position: relative;
}
markercenter, markerbottom, markerfixed, monitor {
  /* scaffolding, to be removed */
  display: flex; 
  justify-content: center; 
  align-items: center;
  height: 20px; width: 20px;
  font-size: 14px;
  color: white;
}
markercenter { 
  /* scaffolding, to be removed */
  /* these are here to judge center of screen for testing */
  position: absolute;
  top: 50%; transform: translateY(-50%);
  left: 50%; transform: translateX(-50%);
  background-color: black;
}
markerbottom { 
  /* scaffolding, to be removed */
  /* these are here to judge center of screen for testing */
  position: absolute;
  //top: 50%; transform: translateY(-50%);
  left: 50%; transform: translateX(-50%);
  bottom: -10px;
  height: 20px; width: 20px;
  font-size: 14px;
  color: white;
  background-color: black;
}
markerfixed {
  /* scaffolding, to be removed */
  /* these are here to judge center of screen for testing */
  position: fixed;
  top: 50%; transform: translateY(-50%);
  left: 50%; transform: translateX(-50%);
  height: 20px; width: 20px;
  background-color: rgba(251, 45, 45, 0.7);
}
monitor {
  /* scaffolding, to be removed */
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: 0;
  width: 100px;
  padding: 2px 10px 0px 10px;
  font-size: 14px;
  color: white; font-weight: bold;
  background-color: black;
}
section {
  width: 100%;
	min-height: 100vh;
}
#about{
  background-color: hsla(182, 100%, 85%, 0.5);
}
#services{
  background-color: hsla(61, 99%, 59%, 0.5);
}
#gallery{
  background-color: rgba(195, 251, 45, 0.5);
} 

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<section id="about">
  <markercenter>1</markercenter><markerbottom>1</markerbottom>
</section>
<section id="services">
  <markercenter>2</markercenter><markerbottom>2</markerbottom>
</section>
<section id="gallery">
  <markercenter>3</markercenter><markerbottom>3</markerbottom>
</section>
<monitor></monitor>
<markerfixed></markerfixed> 

小提琴

https://jsfiddle.net/Hastig/9ta3yh52/13/

具有双滚动问题的先前版本

https://jsfiddle.net/Hastig/9ta3yh52/12/

I have a single page navigation site and all sections/navigation elements have min-height set to 100vh. With that I have a smooth scroll snippet to navigate.

If I manual scroll and the section is not centered (like it would if I click on a menu item) I'd like it to be centered after a given amount of time. Note I don't want to disable scroll to just navigate via menu.

I was thinking about some js to be added with the smoothscroll code. Something to check section position offset and if it is not centered, smoothscroll it with some easing function.

https://jsfiddle.net/9ta3yh52/ take this as a reference, If a color is in more than 75% of view port, scroll to that element.

Thx for your help :)

EDIT / SOLUTION:

The closest approach has been given so far by @Hastig Zusammenstellen

https://stackoverflow.com/a/39188110/6717849

You have to modify it to your needs in order to match the number of sections you have. The logic is easy when sections are set to height: 100vh:

if (scrollTop <= sectionHeightHalf) {
    $('html, body').animate({
      scrollTop: $("#section1").offset().top
    }, 300);
  } else if (scrollTop >= sectionHeightHalf && scrollTop <= ($(window).height() * 2 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#section2").offset().top
      }, 300);
  } else if (scrollTop >= sectionHeightHalf && scrollTop <= ($(window).height() * 3 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#section3").offset().top
      }, 300);
  } else if (scrollTop >= sectionHeightHalf && scrollTop <= ($(window).height() * 4 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#section4").offset().top
      }, 300);
  } else if (scrollTop >= sectionHeightHalf && scrollTop <= ($(window).height() * 5 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#section5").offset().top
      }, 300);

// etc etc

  } else if (scrollTop >= ($(window).height() * 2 - sectionHeightHalf)) {
      $('html, body').animate({
        scrollTop: $("#lastsection").offset().top
      }, 300);
  }

解决方案

New version was made using this code which was inspired or based on code from here.

It fixes the double scroll problem from last version but now seems to sometimes stick after it auto centers.

$(function() {
  $(window).scroll(function() {
    $('monitor').html('SCROLLING');
    clearTimeout($.data(this, 'scrollCheck'));
    $.data(this, 'scrollCheck', setTimeout(function() {
      $('monitor').html('PAUSED');
      var sectionHeightHalf = $(window).height() / 2;
      var scrollTop = $(window).scrollTop();
      if (scrollTop <= sectionHeightHalf) {
        $('html, body').animate({
          scrollTop: $("#about").offset().top
        }, 300);
      } else if 
        (scrollTop >= sectionHeightHalf && 
         scrollTop <= ($(window).height() * 2 - sectionHeightHalf)) {
          $('html, body').animate({
            scrollTop: $("#services").offset().top
          }, 300);
        } else if (scrollTop >= ($(window).height() * 2 - sectionHeightHalf)) {
          $('html, body').animate({
            scrollTop: $("#gallery").offset().top
          }, 300);
        }
    }, 300) );
  });
});

html, body {
  margin: 0;
  padding: 0;
}
section {
  position: relative;
}
markercenter, markerbottom, markerfixed, monitor {
  /* scaffolding, to be removed */
  display: flex; 
  justify-content: center; 
  align-items: center;
  height: 20px; width: 20px;
  font-size: 14px;
  color: white;
}
markercenter { 
  /* scaffolding, to be removed */
  /* these are here to judge center of screen for testing */
  position: absolute;
  top: 50%; transform: translateY(-50%);
  left: 50%; transform: translateX(-50%);
  background-color: black;
}
markerbottom { 
  /* scaffolding, to be removed */
  /* these are here to judge center of screen for testing */
  position: absolute;
  //top: 50%; transform: translateY(-50%);
  left: 50%; transform: translateX(-50%);
  bottom: -10px;
  height: 20px; width: 20px;
  font-size: 14px;
  color: white;
  background-color: black;
}
markerfixed {
  /* scaffolding, to be removed */
  /* these are here to judge center of screen for testing */
  position: fixed;
  top: 50%; transform: translateY(-50%);
  left: 50%; transform: translateX(-50%);
  height: 20px; width: 20px;
  background-color: rgba(251, 45, 45, 0.7);
}
monitor {
  /* scaffolding, to be removed */
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: 0;
  width: 100px;
  padding: 2px 10px 0px 10px;
  font-size: 14px;
  color: white; font-weight: bold;
  background-color: black;
}
section {
  width: 100%;
	min-height: 100vh;
}
#about{
  background-color: hsla(182, 100%, 85%, 0.5);
}
#services{
  background-color: hsla(61, 99%, 59%, 0.5);
}
#gallery{
  background-color: rgba(195, 251, 45, 0.5);
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<section id="about">
  <markercenter>1</markercenter><markerbottom>1</markerbottom>
</section>
<section id="services">
  <markercenter>2</markercenter><markerbottom>2</markerbottom>
</section>
<section id="gallery">
  <markercenter>3</markercenter><markerbottom>3</markerbottom>
</section>
<monitor></monitor>
<markerfixed></markerfixed>

fiddle

https://jsfiddle.net/Hastig/9ta3yh52/13/

prior version with double scroll problem

https://jsfiddle.net/Hastig/9ta3yh52/12/

这篇关于在给定的时间后,平滑滚动到当前部分的中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆