在给定的时间后,平滑滚动到当前部分的中心 [英] Smooth Scroll to center current section after a given amount of time
问题描述
我有一个页面导航站点,所有部分/导航元素的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屋!