JavaScript Smooth Scrolling effect with scrollIntoView - javascript

Okay, I am attempting to get a single page (two divs), Primarily a splash screen, which when you click 'Enter site' and it will scroll down smoothly to the 'main site', However it jumps to it, rather than smooth scrolling to the element.
How would can I get it to scroll to that element smoothly without this jump effect?
Here is my a snippet:
splash = document.getElementById('intro');
content = document.getElementById('content');
function enterSite() {
content.scrollIntoView({
behaviour: "smooth"
});
}
body {
font-family: 'Archivo Narrow', sans-serif;
margin: 0 auto;
width: 100%;
height: 100%;
}
html,
body {
overflow: hidden;
}
main {
width: 100%;
height: 100%;
position: relative;
}
#intro {
background-image: url(https://i.imgsafe.org/51d0cf26df.jpg);
background-repeat: no-repeat;
background-size: cover;
display: flex;
text-align: center;
height: 100%;
}
#splash {
margin: auto;
width: 40%;
background-color: rgba(56, 56, 56, 0.4);
border-radius: 50px 50px;
}
#splash-p {
width: 70%;
font-size: 1.2em;
line-height: 1.5em;
margin: auto;
text-align: center;
padding-top: 10px;
color: #fff;
}
.btn {
width: 35%;
margin: auto;
margin-top: 10px;
margin-bottom: 10px;
}
/* Main Content Page */
article {
position: absolute;
width: 100%;
height: 100%;
background-color: red;
}
<div id="intro">
<div id="splash">
<p id="splash-p">Just a load of text repeated</p>
<input
type="image"
src="Images/Button.png"
class="btn"
onclick="enterSite()"
/>
</div>
</div>
<article id="content">Just a load of text repeated</article>
If you click the button it will jump to the next div, but i need it to scroll smoothly rather than jump to the next div, Using pure javascript, everywhere else i have looked seems to have plug ins or uses jquery.

If you don't want a straight jump, you should animate the scroll somehow.
With the help of jQuery is easy as that:
$("html, body").animate({ scrollTop: $([ELEMENT]).position().top }, 1000);
Look at this fiddle: https://jsfiddle.net/8501ckvn/
jQuery solves a lot of cross browser issues, but if you are looking for a pure javascript solution there are already many answers on Stackoverflow, i.e. look at Smooth scroll anchor links WITHOUT jQuery.

Your content.scrollIntoView({behaviour: "smooth"}); should work, however, I think 'behaviour' is spelt behavior.
I did develop a way of smooth scrolling with TypeScript, but you should be able to convert to JS quite easily:
View stackoverflow answer

For a more comprehensive list of methods for smooth scrolling, see my answer here.
To scroll to a certain position in an exact amount of time, window.requestAnimationFrame can be put to use, calculating the appropriate current position each time. setTimeout can be used to a similar effect when requestAnimationFrame is not supported.
/*
#param pos: the y-position to scroll to (in pixels)
#param time: the exact amount of time the scrolling will take (in milliseconds)
*/
function scrollToSmoothly(pos, time) {
var currentPos = window.pageYOffset;
var start = null;
if(time == null) time = 500;
pos = +pos, time = +time;
window.requestAnimationFrame(function step(currentTime) {
start = !start ? currentTime : start;
var progress = currentTime - start;
if (currentPos < pos) {
window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
} else {
window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
}
if (progress < time) {
window.requestAnimationFrame(step);
} else {
window.scrollTo(0, pos);
}
});
}
Demo:
function scrollToSmoothly(pos, time) {
var currentPos = window.pageYOffset;
var start = null;
if(time == null) time = 500;
pos = +pos, time = +time;
window.requestAnimationFrame(function step(currentTime) {
start = !start ? currentTime : start;
var progress = currentTime - start;
if (currentPos < pos) {
window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
} else {
window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
}
if (progress < time) {
window.requestAnimationFrame(step);
} else {
window.scrollTo(0, pos);
}
});
}
document.getElementById("toElement").addEventListener('click', function(e) {
var elem = document.querySelector("div");
scrollToSmoothly(elem.offsetTop);
});
document.getElementById("toTop").addEventListener('click', function(e){
scrollToSmoothly(0, 700);
});
<button id="toElement">Scroll To Element</button>
<div style="margin: 1000px 0px; text-align: center;">Div element
<button id="toTop">Scroll back to top</button>
</div>
For more complex cases, the SmoothScroll.js library can be used, which handles smooth scrolling both vertically and horizontally, scrolling inside other container elements, different easing behaviors, scrolling relatively from the current position, and more.
document.getElementById("toElement").addEventListener('click', function(e) {
smoothScroll({toElement: document.querySelector('div'), duration: 500});
});
document.getElementById("toTop").addEventListener('click', function(e){
smoothScroll({yPos: 0, duration: 700});
});
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/SmoothScroll#1.2.0/src/smoothscroll.min.js" integrity="sha384-UdJHYJK9eDBy7vML0TvJGlCpvrJhCuOPGTc7tHbA+jHEgCgjWpPbmMvmd/2bzdXU" crossorigin="anonymous"></script>
<button id="toElement">Scroll To Element</button>
<div style="margin: 1000px 0px; text-align: center;">Div element
<button id="toTop">Scroll back to top</button>
</div>
Alternatively, you can pass an options object to window.scroll which scrolls to a specific x and y position and window.scrollBy which scrolls a certain amount from the current position:
// Scroll to specific values
// scrollTo is the same
window.scroll({
top: 2500,
left: 0,
behavior: 'smooth'
});
// Scroll certain amounts from current position
window.scrollBy({
top: 100, // could be negative value
left: 0,
behavior: 'smooth'
});
Demo:
<button onClick="scrollToDiv()">Scroll To Element</button>
<div style="margin: 500px 0px;">Div</div>
<script>
function scrollToDiv(){
var elem = document.querySelector("div");
window.scroll({
top: elem.offsetTop,
left: 0,
behavior: 'smooth'
});
}
</script>
Modern browsers support the scroll-behavior CSS property, which can be used to make scrolling in the document smooth (without the need for JavaScript). Anchor tags can be used for this by giving the anchor tag a href of # plus the id of the element to scroll to). You can also set the scroll-behavior property for a specific container like a div to make its contents scroll smoothly.
Demo:
html, body{
scroll-behavior: smooth;
}
Scroll To Element
<div id="elem" style="margin: 500px 0px;">Div</div>

Assuming that you have JQuery as well.
You could make use of the following JQuery code to get a smooth scrolling effect
function enterSite(){
$('html, body').stop().animate({
scrollTop: $('#content').offset().top
}, 1500);
});
Let me know if it worked

Related

How can I make the width of an Element incease while scrolling?

I tried to make the width of the div increase while scrolling down.
Who know how to do this with pure JS?
.about {
overflow: hidden;
z-index: 2;
width: 50%;
height: 100vh;
display: flex;
padding: 10vw 0;
margin: 0 auto;
background: url('./img/pexels-alesia-kozik-5989895.jpg') no-repeat;
transition: width .5s;
}
<div class="about">
<div class="container">
<h6 class="font_caps">/ Introduction</h6>
<h2 class="lead">Accelerating Global Brands — Years ahead.</h2>
<p class="lead">We are a world—class team of industry—leading professionals, who constantly push new technology to its limits.</p>
</div>
</div>
First, you get access to the div with the about class.
let aboutDiv = document.querySelector(".about");
Next, you add a scroll event-listener to window, with a callback function.
window.addEventListener("scroll", (e) => {
});
You want the height of the div to increase only when scrolling down. So, in the callback function you add that restriction.
Replace the previous code with:
let lastScroll = window.scrollY;
let inc = 1; //inc is the amount you wish to increment the div's height by
window.addEventListener("scroll", (e) => {
if(window.scrollY - lastScroll > 0) {
aboutDiv.style.height = `${aboutDiv.getBoundingClientRect().height + inc}px`
}
lastScroll = window.scrollY;
})
You can use the code below if you wish to increase the height of the div by the magnitude of the scroll change.
aboutDiv.style.height = `${aboutDiv.getBoundingClientRect().height + window.scrollY - lastScroll}px`
If you wish to decrease the height while scrolling up, add this too:
let dec = 1; //dec is the amount you wish to decrement the div's height by
window.addEventListener("scroll", (e) => {
if(window.scrollY - lastScroll < 0) {
aboutDiv.style.height = `${aboutDiv.getBoundingClientRect().height - dec}px`
}
lastScroll = window.scrollY;
})
From what I understand, you want increasing the width of your 'about' section when scrolling down, right? If yes, I applied an event on the body (or parent element) of scroll and checked using just the window scrollY, but probably in your context it's different. Here's the example:
let body = document.body;
body.onscroll = (ev) => {
const target = body; // here is ev.target
const about = target.querySelector('.about');
const width = window.scrollY ? '100%' : '50%';
return about.style.width = width; // better: you can add class on about section and edit style according to this classname on css
}
.about {
overflow: hidden;
z-index: 2;
width: 50%;
height: 100vh;
display: flex;
padding: 30px 0;
margin: 0 auto;
background: url('https://www.quickanddirtytips.com/wp-content/uploads/2022/04/grammar-devotional.jpg') no-repeat;
transition: width .5s;
}
<div class="about">
<div class="container">
<h6 class="font_caps">/ Introduction</h6>
<h2 class="lead">Accelerating Global Brands — Years ahead.</h2>
<p class="lead">We are a world—class team of industry—leading professionals, who constantly push new technology to its limits.</p>
</div>
</div>

Opacity reduction script does not working

I have a problem with a script that until recently worked, but now seems not to want to work.
I want to reduce the opacity of the green spheres when scrolling down, it seems to be working until recently, but now I can't figure out what the problem is.
The website is this: https://attiliosantomo.com/PROVA/
The script is this:
$(document).ready(function() {
$(window).scroll(function(event) {
let scroll = $(this).scrollTop();
let opacity = 1 - (scroll / 1300);
if (opacity > 0.2) {
$('.bg-bubble').css('opacity', opacity);
}
});
});
</script>
Thank you so much for you help
The issue is that it's not the window that is scrolling. It's the .main-desktop element that is being scrolled. Targeting the scroll event of the .main-desktop as per below should solve the issue.
$(document).ready(function() {
// \/ Changed \/ selector from window to '.main-desktop'
$('.main-desktop').scroll(function(event) {
let scroll = $(this).scrollTop();
let opacity = 1 - (scroll / 1300);
if (opacity > 0.2) {
$('.bg-bubble').css('opacity', opacity);
}
});
});
html,
body {
height: 100%;
margin: 0;
}
.main-desktop {
overflow: scroll;
height: 100%;
}
.inner {
height: 3000px;
}
.bg-bubble {
height: 100px;
width: 100px;
background-color: blue;
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bg-bubble"></div>
<div class="main-desktop">
<div class="inner"></div>
</div>

Is there any way to change a div size on scroll using intersectionObserver?

I'm trying to change the size (or scale) of a div while scrolling.
This div has a .8 scale attached to it css. I'd like to reach a scale of 1 progressively while scrolling.
IntersectionObserver seems to be a good choice to work with instead of scroll event but i don't know if i can change the state of an element using it.
You can change the scale of a div using.
document.getElementById("scaledDiv").style.transform = "scale(1)";
The scroll event should do what you want it to do. You can continue to add more if statements and check how many pixels they are scrolling to change it gradually to 1 or even back to 0.8 when they scroll back up. The 50 below represents 50 pixels from the top of the page.
window.onscroll = function() {
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
// They are scrolling past a certain position
document.getElementById("scaledDiv").style.transform = "scale(1)";
} else {
// They are scrolling back
}
};
I hope this will help you:
const container = document.querySelector('.container');
const containerHeight = container.scrollHeight;
const iWillExpand = document.querySelector('.iWillExpand');
container.onscroll = function(e) {
iWillExpand.style.transform = `scale(${0.8 + 0.2 * container.scrollTop / (containerHeight - 300)})`;
};
.container {
height: 300px;
width: 100%;
overflow-y: scroll;
}
.scrollMe {
height: 1500px;
width: 100%;
}
.iWillExpand {
position: fixed;
width: 200px;
height: 200px;
top: 10px;
left: 10px;
background-color: aqua;
transform: scale(0.8);
}
<div class='container'>
<div class='scrollMe' />
<div class='iWillExpand' />
</div>

Horizontal parallax effect to text on scroll

So I sort of got it working. I believe I am not understanding the javascript correctly.
I took this from another thread, however it isn't behaving quite the way I am trying to achieve. I see the variables are a math equation that bases the movement on the window height.
How can I manipulate the equation so that I can control "Some cool text."'s initial position (if you notice on load it takes the correct position, and then on scroll it gets moved by JS) to stay where I want it?
What controls the speed and intensity of the movement and how can I manipulate that?
I believe I am just not understanding the syntax that controls all these variables, can you point me in the right direction for some reading to understand these specific variables? Thank you. :D
https://jsfiddle.net/codingcrafter/kv9od1ju/22/
/* Custom Horizontal Scrolling Parallax */
.hero-two {
overflow: hidden;
position: relative;
min-height: 500px;
}
h1 {
-webkit-text-stroke-width: 0.1rem;
-webkit-text-stroke-color: black;
color: #fff;
font-family: 'Open Sans', Helvetica, Times New Roman !important;
font-weight: 900;
}
.para-ele {
position: absolute;
width: 100%;
font-size: 5rem;
}
#hero-first {
left: 75%;
top: 15%;
}
#hero-second {
left: -32%;
bottom: 10%;
}
.container {
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
}
<div class="container">
<div class="hero-two">
<h1 id="hero-first" class="h1 para-ele">
Some cool text.
</h1>
<h1 id="hero-second" class="h1 para-ele">
Some boring text.
</h1>
</div>
</div>
$(document).ready(function() {
var $horizontal = $('#hero-first');
$(window).scroll(function() {
var s = $(this).scrollTop(),
d = $(document).height(),
c = $(this).height();
scrollPercent = (s / (d - c));
var position = (scrollPercent * ($(document).width() - $horizontal.width()));
$horizontal.css({
'left': position
});
});
});
So you want to move the text from left to right or right to left?
I have done something similar to your issue but I used jQuery to handle the scroll effect.
If you are going to use the code below you will need to wrap the text within a element with the class Introduction
As the page scrolls the element will append the styles dynamically to the element.
<h1 class="introduction">
WE ARE A <br><span class="d">DIGITAL</span><br>PARTNER
</h1>
$(window).scroll(function() {
var wScroll = $(this).scrollTop();
$(".introduction").css({
transform: "translateX(-" + wScroll / 23 + "%)"
})
});
Demo: https://guide-nancy-64871.netlify.com/
When page is scrolled the header text moves to the left.
Read more on css transform: https://css-tricks.com/almanac/properties/t/transform/
Hope this helps!

Revealing / Hiding Fixed Menu (jQuery)

I am trying to fix and animate a header navigation so that it pops down from outside of the browser window when a user scrolls past 80px from the top. I then want to reverse the animation when the user scrolls back past <80px. I have gotten this far (have set throttle function earlier in the code):
var e = $(window).scrollTop();
$(window).on("scroll", throttle(function() {
var t = $(window).scrollTop();
t > 80 ? t > e ? $(header).animate({
top: "-150px"
}, 200) :
At the 'else' point I am totally stuck. I've been looking at other similar functions and trying to interpret the code but really struggling. Any help hugely appreciated.
Why are you comparing it with e (which will be usually 0). That's no point. If you want something to happen when the window's scrollTop becomes 80px, just use the following code. Also please not the single true parameter in the animate's stop() function.
$(function () {
$(".peek-a-boo").css({
top: -200
});
$(window).scroll(function () {
if ($(window).scrollTop() > 80)
$(".peek-a-boo").stop(true).animate({
top: 0
}, 200);
else
$(".peek-a-boo").animate({
top: -200
}, 200);
});
});
* {box-sizing: border-box;}
.peek-a-boo {position: fixed; background-color: #99f; width: 100%; top: 0; left: 0; padding: 5px; text-align: center;}
.heighter {height: 1000px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<header class="peek-a-boo">Peek</header>
<div class="heighter"></div>

Categories