问题
I am trying to add an on-click-smooth-scroll effect like this one: https://michalsnik.github.io/aos/
I have read this: Smooth scroll to specific div on click and I am unable to adapt it. I don't understand what scrollTop: $("#page2").offset().top
does.
My issue is that the scroll is "snapping". And that's probably because I have applied scroll-snap
on the containers.
Also, when you're in-between the pages and click on the scroll down arrow it will either move up or down.
I would like to get the second page on full view whenever I press on that arrow. It should Scroll Down until #page2
has height: 100vh
or it occupies the whole view port.
// eliminate scroll-bar
var child = document.getElementById('child-container');
child.style.right = child.clientWidth - child.offsetWidth + "px";
//scroll down effect on scroll-down-arrow
$(".scroll-down-arrow").click(function() {
$('html,body,#child-container').animate({scrollTop: $("#page2").offset().top}, 'slow', 'linear');
});
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* *** index.html - START *** */
body, html {
height: 100%;
width: 100%;
overflow: hidden;
}
#parent-container {
height: 100%;
width: 100%;
overflow: hidden;
position: relative;
}
#child-container {
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px; /* exact value is given through JavaScript */
overflow: auto;
scroll-snap-type: both proximity;
}
header {
height: 100%;
background-color: grey;
background-attachment: fixed;
background-position: bottom center;
background-repeat: no-repeat;
background-size: cover;
text-align: center;
scroll-snap-align: center;
}
header h1 {
font-size: 32px;
font-weight: bold;
position: sticky;
top: 5%;
margin-bottom:10px;
}
header p {
position: sticky;
width: 450px;
text-align: center;
margin: auto;
margin-top: 100px;
font-size: 1.5em;
}
header .scroll-down-arrow {
position: absolute;
left: 50%;
bottom: 20px;
display: block;
text-align: center;
font-size: 20px;
z-index: 100;
text-decoration: none;
text-shadow: 0;
width: 30px;
height: 30px;
border-bottom: 2px solid #fff;
border-right: 2px solid #fff;
left: 50%;
transform: translate(-50%, 0%) rotate(45deg);
animation: fade_move_down 3s ease-in-out infinite;
cursor: pointer;
}
/*animated scroll arrow animation*/
@keyframes fade_move_down {
0% { transform:translate(0,-15px) rotate(45deg); opacity: 0; }
25% {opacity: 1;}
/* 50% { opacity: 1; } */
100% { transform:translate(0,10px) rotate(45deg); opacity: 0; }
}
.container_page_2 {
width: 100%;
height: 100vh;
scroll-snap-align: center;
overflow: hidden;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div id="parent-container">
<div id="child-container">
<!-- #header -->
<header>
<div class="nav-container">
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<a href="#page2"><h1 id="sticky-title">Lorem ipsum</h1></a>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Modi debitis in libero tenetur suscipit iusto eum nulla dolorum aperiam adipisci unde veritatis vel iure, a nam, saepe exercitationem illum vitae.</p>
<div class="scroll-down-arrow"></div>
</header>
<!-- #page2 -->
<div id="page2" class="container_page_2">
<div class="column active">
<div class="content">
<h1>1</h1>
<div class="box">
<h2>background-attachment: fixed;</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Inventore necessitatibus possimus fuga voluptate incidunt enim eius sed, ad suscipit error quasi ex blanditiis ipsa, at vero officiis voluptatem a modi!
</p>
</div>
</div>
<div class="bg bg1"></div>
</div>
<div class="column">
<div class="content">
<h1>2</h1>
<div class="box">
<h2>background-attachment: scroll;</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Inventore necessitatibus possimus fuga voluptate incidunt enim eius sed, ad suscipit error quasi ex blanditiis ipsa, at vero officiis voluptatem a modi!
</p>
</div>
</div>
<div class="bg bg2"></div>
</div>
<div class="column">
<div class="content">
<h1>3</h1>
<div class="box">
<h2>background-attachment: scroll;</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Inventore necessitatibus possimus fuga voluptate incidunt enim eius sed, ad suscipit error quasi ex blanditiis ipsa, at vero officiis voluptatem a modi!
</p>
</div>
</div>
<div class="bg bg3"></div>
</div>
<div class="column">
<div class="content">
<h1>4</h1>
<div class="box">
<h2>background-attachment: fixed;</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Inventore necessitatibus possimus fuga voluptate incidunt enim eius sed, ad suscipit error quasi ex blanditiis ipsa, at vero officiis voluptatem a modi!
</p>
</div>
</div>
<div class="bg bg4"></div>
</div>
</div>
https://codepen.io/bleah1/pen/gjYBgQ
I haven't added all the elements from the second page, but it doesn't matter, because the scrolling isn't affected. As you can see it's not smooth at all, it's actually pretty snappy.
What do you think ? I would like to keep the scroll-snap, because I like that idea.
回答1:
Hi can you try this solution.
Basically I removed the css when click event starts then added it when the scrollTop event ends.
Remember to remove it from your css #child-container
$(".scroll-down-arrow").click(function() {
$('#child-container').css('scroll-snap-type','')
$('html,body,#child-container').animate({
scrollTop: $("#page2").offset().top}, 'slow', 'linear')
.promise()
.done(() => {$('#child-container')
.css('scroll-snap-type','both proximity')
});
});
回答2:
Based on @Ekin Alcar answer I was able to fix my issue. I followed his idea of removing the scroll-snap-type
css attribute from #child-container
by using $('#child-container').css('scroll-snap-type','');
inside of the original script, like this:
$(".scroll-down-arrow-container").click(function() {
$('#child-container').css('scroll-snap-type','');
$('html, body, #child-container').animate({
scrollTop: $(window).height()
}, 1000)
.promise()
.done(() => {$('#child-container')
.css('scroll-snap-type','both proximity')
});
});
The trick with .css
is that it can only remove attributes that are used in the style
tag inside a .html
file. It won't work with a .css
stylesheet.
From the API's documentation:
It does not, however, remove a style that has been applied with a CSS rule in a stylesheet or < style > element.
As such scroll-snap-type: both proximity;
was removed from the .css
file and added in the .html
file:
<div id="child-container" style="scroll-snap-type: both proximity;">
Also, to fix the effect of scrolling up or down whenever you're in between pages I've replaced scrollTop: $("#page2").offset().top
with scrollTop: $(window).height()
. Don't ask me why it works, but it does.
来源:https://stackoverflow.com/questions/59395345/smooth-scroll-isnt-smooth-at-all-smooth-scroll-only-scrolls-a-number-of-pixels