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>
Related
I have a web page with two 100% height divs like this...
<style>
html, body{
height: 100%;
width: 100%;
margin: 0;
overflow: hidden;
}
#wrapper{
height:100%;
width:100%;
overflow: auto;
}
.scroll-item{
height: 100%;
width: 100%;
}
</style>
...
<body>
<div id="wrapper">
<div id="test1"
class="scroll-item">Simple Test 1</div>
<div id="test2"
class="scroll-item">Simple Test 2</div>
</div>
</body>
Now I want to "select" the one that is currently scrolled to. This means that the top of the element has reached the top of the browser but the bottom has not. This is where I am getting confused here is the JS...
<script type="module">
const body = document.getElementsByTagName("body")[0];
const handleScroll = function(info){
const items = body.getElementsByClassName("scroll-item");
for(let i = 0; i < length; i++){
const item = items[i];
// TODO How do I tell if it is there
}
}
body.addEventListener("wheel",handleScroll);
</script>
I have tried using the bounding box but I cannot figure out how to get that to work correctly.
How do I tell when the top or bottom of the element reaches the top of the browser (given possible offset for navbar)?
You can use getBoundingClientRect().
It gives you the DOMRect object containing the size and coordinates of an element.
...
if (item.getBoundingClientRect().top < 0) {
// items top has reached beyond window top
}
if (item.getBoundingClientRect().bottom > window.innerHeight) {
// items bottom is beyond window bottom
}
...
For advanced usage, see IntersectionObserver, which detects an elements visibility inside the viewport.
Use the wrapper to get current position and listen scroll event, also, is better to listen scroll instead of wheel event.
// Use the wrapper to get and listen scroll
const wrapper = document.querySelector('#wrapper')
const handleScroll = function(event) {
const top = wrapper.scrollTop;
document.querySelectorAll('.scroll-item').forEach((item, index) => {
// Calculate item bottom position
const bottom = item.offsetTop + item.offsetHeight;
// Is the scroll between item top and bottom?
if(top >= item.offsetTop && top < bottom) {
console.log(`Item ${index} is active`);
}
});
}
// scroll event is more accurate than wheel
wrapper.addEventListener("scroll", handleScroll);
html, body{
height: 100%;
width: 100%;
margin: 0;
overflow: hidden;
}
#wrapper{
height:100%;
width:100%;
overflow: auto;
}
.scroll-item{
height: 100%;
width: 100%;
}
<body>
<div id="wrapper">
<div id="test1"
class="scroll-item">Simple Test 1</div>
<div id="test2"
class="scroll-item">Simple Test 2</div>
</div>
</body>
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>
I want to make a fixed element (like sticky) when I scroll and reach the top of another element. The fixed element will increase the bottom property of css to don't pass the top of the element I set as bound (the element you can't pass the point, like a ground). I did a pen that shows what I want, hope that helps: https://codepen.io/vendramini/pen/xNWpPK. I really don't know which calculation I need to do to achieve this. Please, help me.
https://codepen.io/vendramini/pen/xNWpPK
The best I could do to exemplify this.
*{
margin: 0;
padding: 0;
}
section{
height: 100vh;
width: 100vw;
background: #eee;
position: relative;
max-width: 100%;
}
.a{
background: #faa;
}
.b{
background: #ffa;
}
.c{
background: #afa;
}
.d{
background: #aaf;
}
.sticky{
width: 100%;
position: fixed;
height: 100px;
background: blue;
opacity: 0.5;
bottom: 0;
z-index: 1;
}
.ground{
height: 2000px;
background: black;
}
//jQuery required
(function($){
$('[data-bound]').each(function(){
const $elem = $(this);
const $bound = $( $elem.data('bound') );
$(window).scroll(function(){
const scrollTop = $(window).scrollTop();
const boundTop = $bound.offset().top;
const boundHeight = $bound.height();
const delta = (scrollTop - boundTop); //+ boundHeight;
console.log({
scrollTop,
boundTop,
delta,
});
if( delta > 0 ){
$elem.css('bottom', delta);
}
else{
$elem.removeAttr('style');
}
});
});
})(jQuery);
<div class="sticky" data-bound="#ground"></div>
<section class="a"></section>
<section class="b"></section>
<section class="c"></section>
<section class="d"></section>
<footer class="ground" id="ground"></footer>
<section class="a"></section>
<section class="b"></section>
<section class="c"></section>
<section class="d"></section>
I expect to have a fixed element that doesn't pass the ground element. That's it.
I'm not sure I understand exactly what you want, but I think you can achieve this with only CSS using position: sticky on the footer.
https://codepen.io/anon/pen/jozzPq
the relevante changes:
add a wrapper to the elements with the sticky footer:
<div>
<section class="a"></section>
<section class="b"></section>
<section class="c"></section>
<section class="d"></section>
<footer class="ground" id="ground"> </footer>
</div>
position the footer at the bottom and set it to sticky
.ground{
height: 100px;
background: black;
position: sticky;
bottom: 0;
}
Check the codepen cause a lot of CSS and (all) JS can be removed.
I finally found the answer:
https://codepen.io/vendramini/pen/xNWpPK
The solution is add the window's height in to the delta calculation:
const windowHeight = $(window).height();
const delta = (scrollTop - boundTop) + windowHeight;
Thanks everyone that contributed to this thread!
Replace
if( delta > 0 ){
$elem.css('bottom', delta);
}
else{
$elem.removeAttr('style');
}
with
$elem.css('bottom', 0);
to stick the element always to the bottom.
The thing that I want is next to what UIKit does:
https://getuikit.com/docs/sticky
But the problem is that UIKit uses top instead of bottom.
Here is the code that i have so far:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 120) {
$("#FixedBox").addClass("fixed");
} else {
$("#FixedBox").removeClass("fixed");
}
});
With this code when the page is scrolled with 120px it add the class fixed to the element with id FixedBox.
What i want?
The element with id FixedBox is contained in element with id Content. So when the page is scrolled with 120 px my script attaches fixed class to FixedBox which makes it fixed.
How can i remove that fixed class when FixedBox reaches the end of Content ?
Here is an image in example:
How i can achieve that?
I hope you can help me!
You could make a function which checks if the scroll height is in between the start and the end of the content and adds the class accordingly. This would even work if you have several blocks of content.
Live Demo (3rd content box is the target)
HTML
<div class="content">
<div class="box">
</div>
</div>
<div class="content" id="target">
<div class="box">
</div>
</div>
CSS
.content{
width: 100%;
height: 400px;
background: red;
margin-bottom: 20px;
position: relative;
}
.fixed{
width: 100px;
height: 100px;
position: fixed;
right: 10px;
top: 10px;
background: blue;
display: block;
}
jQuery
var content = $('#target');
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var offset = content.offset();
var height = content.height();
if (offset.top <= scroll && scroll <= offset.top + height) {
$('.box', content).addClass("fixed");
} else {
$('.box', content).removeClass('fixed');
}
});
You can find the end of your content by finding its position by $('#content').offset() or $('#footer').offset() more in the jQuery API Docs.
When you calculate the height of your elements and positions you can figure out the top threshold where you need to remove the fixed class of the FixedBox. Keep in mind that you also need to alter the non-fixed position of your FixedBox when it returns to the DOM flow, else it will snap back to the starting position.
`
var maxScroll = 120 + document.getElementById('#content').offsetHeight;
if (scroll >= 120 && scroll <= maxScroll) {
$("#FixedBox").addClass("fixed");
} else {
$("#FixedBox").removeClass("fixed");
}
You just need to get #content height.
There is a div, style fixed 60px from top. I want when I scroll down and the distance of div from top reached 10px, the div stop there for the rest of scrolling also when I scroll up it goes back to the old style 60px from top. I did a lot of search but I did not found anything like this. But there is a code which calculate distance from top:
var scrollTop = $(window).scrollTop(),
elementOffset = $('#my-element').offset().top,
distance = (elementOffset - scrollTop);
Here's one way to do it using pure javascript. You can replace some of the selectors like document.getElementById with jQuery selectors like $("id") if you like.
window.onscroll = function(){
var el = document.getElementById('sticky'),
s = window.pageYOffset || document.documentElement.scrollTop, // how much page is scrolled
t = document.getElementById('main').getBoundingClientRect().top; // top of main div
if(s > t){
el.style.position = 'fixed'; //make position fixed instead of absolute
}else{
el.style.position = ''; //clear styles if back to original position
}
}
body {
min-height: 200em;
margin: 0;
padding: 0;
}
header {
background: black;
color: white;
padding: .5em;
}
#main { position: relative; } /* important so the sticky box positions relative to this */
#sticky {
background: cornflowerblue;
padding: .5em;
position: absolute;
right: 1em;
top: 1em;
width: 10em;
color: white;
}
<header>This is just a page header or toolbar.</header>
<section id="main">
<div id="sticky">This should stick to the top when scrolled.</div>
</section>
Here's a jQuery solution. If we're more than 10px from the top of the page add a is-sticky class to the element which you can then style with CSS.
// store the element in a variable
var element = $('.item'),
visible = false;
// on scroll
$(window).scroll(function() {
/**
* store the scroll distance in px
* from the top of the viewport
*/
var scroll = $(window).scrollTop();
/**
* if the scroll is greater than or equal
* to 10px add a class of .is-sticky to the element
* otherwise we're less than 10px from the top
* of the document and therefore don't want
* the element to have the .is-sticky class
*/
if(scroll >= 10) {
if(!visible) {
element.addClass('is-sticky');
visible = true;
}
} else {
if(visible) {
element.removeClass('is-sticky');
visible = false;
}
}
});