I have some sections and want to set the height of a separate div (fixed) depending to the scrolling (for a parallax effect). Every scroll action $(window).scroll(function() {...}); the following code is fired. That works fine, but very laggy, because of the CPU usage, I think.
You know how to get the whole thing into the GPU usage with translate or something else.
var windowHeight = $(window).height();
var sectionNumber = 0;
$("main section").each(function() {
sectionNumber++;
var secPosition = $(this).position();
if( ( $(window).scrollTop() + windowHeight ) > secPosition.top ) {
var secScrollValue = ($(window).scrollTop() + windowHeight) - secPosition.top;
$(".parallaxBg" + sectionNumber).css("height", (windowHeight - secScrollValue) + "px");
} else {
$(".parallaxBg" + sectionNumber).css("height", "100%");
}
});
the parallax divs (without the section-numbers):
.parallaxBg {
position: fixed;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
background-position: 0px 0px;
background-size: 100%;
background-repeat: repeat-x;
background-attachment: fixed;
background-image: ...;
}
Here is a sample: http://jsfiddle.net/c5axqoo1/
On retina and with more content its a way more laggy!
Why I used height? Because I want the background-position fixed.
Pre-Thanks :)
You could animate translateY so it uses GPU
Here's a plugin that can might help you:
http://ricostacruz.com/jquery.transit/
Related
To clarify what I'm trying to do:
I have a fixed background image which should move slightly when the user scrolls, which is already working. But when the image disappears I want it to appear again at the beginning of the screen.
The image is just an example, it will be a svg which is going to be 100% wide, so the image has to appear at the screen again as soon as it has left: 1px already.
How do I do that?
Here's my code
https://codepen.io/anon/pen/YaMJyG
var offset = $("#moving-element").offset();
$(window).scroll(function(event) {
var st = $(this).scrollTop();
$("#moving-element").css("left", st + offset.left);
});
body {
height: 9999px
}
#moving-element {
height: 100px;
width: 100%;
background: url('https://vignette.wikia.nocookie.net/nintendo/images/5/5c/Jumping_Mario_Artwork_-_New_Super_Mario_Bros._Wii.png/revision/latest?cb=20120318204810&path-prefix=en');
background-repeat: no-repeat;
background-size: contain;
background-position: bottom left;
position: fixed;
bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="moving-element">
</div>
Update variable st by st%width , where width is div width. So whenever , it becomes more than div width, it again resets automatically
var offset = $("#moving-element").offset();
var width = $("#moving-element").width();
$(window).scroll(function(event) {
var st = $(this).scrollTop();
st = st%width;
$("#moving-element").css("left", st + offset.left);
});
I've seen a lot of question related to modifying an element opacity when user scrolls but haven't found one that helps me the way I need. I have tried several formulas and haven't been able to achieve the effect I want.
I have a header with a BG image, and inside it a div that I use as an overlay, and I want it to get darker and darker smoothly (opacity increase) while the user scrolls down.
EDIT:
The desired effect is:
Opacity is by default set to 0.2 in CSS. When user starts scrolling down it will start increasing from 0.2 to 1. When user scrolls up again it will decrease from 1 (or whatever value it was) to 0.2.
Fiddle: https://jsfiddle.net/z7q2qtc6/
<div class='nice-header'>
<div class='header-overlay'></div>
</div>
CSS
.nice-header {
position: relative;
height: 300px;
background: center center;
background-size: cover;
background-image: url(http://www.boeing.com/resources/boeingdotcom/commercial/787/assets/images/marquee-787.jpg);
}
.header-overlay {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgb(0,0,0);
opacity: 0.2;
}
JS
$(window).scroll(function() {
$('.header-overlay').css({
opacity: function() {
var opacity = 0;
//TODO:
//Set opacity to a higer value whilst user scrolls
return opacity;
}
});
});
You can retrieve the current scrolling position by using the .scrollTop() method.
To calculate the opacity, subtract the scrollTop value from the height of the element and then divide that by the element's height.
Example Here
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
$('.header-overlay').css({
opacity: function() {
var elementHeight = $(this).height();
return 1 - (elementHeight - scrollTop) / elementHeight;
}
});
});
If you want to account for the element's initial opacity of 0.2:
Updated Example
$('.header-overlay').css({
opacity: function() {
var elementHeight = $(this).height(),
opacity = ((1 - (elementHeight - scrollTop) / elementHeight) * 0.8) + 0.2;
return opacity;
}
});
For anyone trying to do this but in the reverse (the elements fades out as you scroll)
opacity = ((elementHeight - scrollTop) / elementHeight);
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
$('.header-overlay').css({
opacity: function() {
var elementHeight = $(this).height(),
opacity = ((elementHeight - scrollTop) / elementHeight);
return opacity;
}
});
});
.nice-header {
position: relative;
height: 300px;
background: center center;
background-size: cover;
background-image: url(http://www.boeing.com/resources/boeingdotcom/commercial/787/assets/images/marquee-787.jpg);
}
.header-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgb(0, 0, 0);
opacity: 1;
}
.dummy {
height: 900px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='nice-header'>
<div class='header-overlay'>
</div>
</div>
<div class='dummy'>
</div>
Use rbga instead of rbg and change the alpha value as the user scrolls. I'm obviously not 100% sure what effect you are going for but in most cases using rgba is a better approach than using rgb and opacity.
What are differences between RGB vs RGBA other than 'opacity'
Here is the link to another post that explains this in further detail.
Pretty new to programming. Manage to do it without JQuery
window.addEventListener(`scroll`, function (e) {
const heroOpas = this.scrollY / 1000;
if (heroOpas === 0) {
sectionHero.style.opacity = 1;
}
if (heroOpas > 0) {
sectionHero.style.opacity = `${1 - heroOpas}`;
}
});
I have a header on a website that is fixed 20px from the top of the page.
However, I want this to catch the top of the page when scrolling and become fixed to the top of the screen once the user has scrolled that 20px down.
CSS
#header{
padding: 0px 0px 0px 0px;
background: url(../images/header-fill2.jpg) repeat-x top;
position: fixed;
height: 60px;
width: 100%;
top: 20px;
z-index: 5000;
}
I imagine some form of JavaScript is required but have little to no JavaScript experience, so any help would be greatly appreciated.
Just listen for the scroll event and read the value of $(window).scrollTop() and set the top according to that.
Something like:
$(window).on('scroll', function() {
$('#header').css('top', $(window).scrollTop() > 20 ? '0px' : '20px');
});
Example on jsFiddle
The scroll event tells you when the window scrolls. Then, use the scrollTop to find out how much closer to 0 to go:
$(window).on("scroll", function() {
$("#header").css("top", Math.max(0, 20 - $(window).scrollTop()));
});
Live Example
Or to avoid constantly re-creating objects:
(function() {
var $wnd = $(window),
$header = $("#header");
$wnd.on("scroll", function() {
$header.css("top", Math.max(0, 20 - $wnd.scrollTop()));
});
})();
Live Example
Thats how I do that with jQuery.
The position is also cached, for performance reasons:
Here is a fiddle:
http://jsfiddle.net/StephanWagner/u3yrS/
$(document).ready(function() {
var cfixed_nav = false, wscroll;
var setScroll = function() {
wscroll = $(window).scrollTop();
var fixed_nav = wscroll > 20; // Set pixel amount here
if (fixed_nav != cfixed_nav) {
$('body')[fixed_nav ? 'addClass' : 'removeClass']('fixed');
cfixed_nav = fixed_nav;
}
};
setScroll();
$(document).scroll(setScroll);
});
With CSS you set the fixed position:
.fixed #header {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%
}
Also remember, that when the header gets the fixed position, those 20px of the header are missing. So you can add a body padding for example:
.fixed {
padding-top: 20px;
}
Or you add an element with 20 Pixel height and swap display none / block depending on the .fixed class in the body
In my project, I need to show a small image in center of the visible part of the container, with respect to the window i.e .loader. Even when the user scrolls the page, the image should be visible in center of .loader.
I successfully implemented this but now I am facing a edgecase which is when user scrolls the page "up to the header" or "down to the footer", the small image is hiding. demo.
This is actually normal behaviour but in these edgecases, I want the image to stick to top/bottom end of the .loader container.
What I want:
Keep the small image always at center of .loader container. (I already implemented this)
when scrolled to any end of .loader container, the image should stick to that end instead of hiding behind the container.
Fiddle
A solution using just css is preferred. I am looking for browser support in IE9+, chrome and firefox.
.header {
height: 600px;
width: 650px;
background-color: grey;
}
.left-side {
height: 300px;
width: 150px;
float: left;
background-color: red;
}
.loader {
background-image: url('http://i.imgur.com/U2njI.jpg');
margin-left: 150px;
height: 1500px;
width: 500px;
background-position: 345px center;
background-repeat: no-repeat;
background-attachment: fixed;
background-color: cornflowerblue;
}
.footer {
height: 600px;
width: 650px;
background-color: silver;
}
<div class="header"></div>
<div class="left-side"></div>
<div class="loader"></div>
<div class="footer"></div>
Here is a working solution with javascript, I hope its behaviour is how you expect it to be. I'm unfortunately not able to test it on IE9 right now but it should work (DEMO):
document.addEventListener('DOMContentLoaded',function() {
var loader = document.querySelector('.loader'),
loaderRect = loader.getBoundingClientRect(),
loaderTop = loaderRect.top + document.body.scrollTop,
loaderBottom = loaderTop + loader.offsetHeight,
initialBgPos = loader.style.backgroundPosition,
imageHeight = 141;
function onScroll() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if(loaderTop >= (scrollTop + (window.innerHeight - imageHeight)/2)) {
loader.style.backgroundPosition='345px ' + (loaderTop - scrollTop) + 'px';
} else if(loaderBottom <= (scrollTop + (window.innerHeight + imageHeight)/2)) {
loader.style.backgroundPosition='345px ' + (loaderBottom - scrollTop - imageHeight) + 'px';
} else {
loader.style.backgroundPosition = initialBgPos;
}
}
window.addEventListener('scroll', onScroll);
onScroll();
});
To achieve what I think you want. We have to set the position of the .loader div to fixed, then it'll always stay where it's placed, regardless of whether the user scrolls the page, the div will scroll too. In here's how to set the position of loader to fixed in CSS (you may also have to get the position of your fixed div):
.loader{
position: fixed;
left: 100px;
top: 300px;
}
Here's your upadted JSFiddle: http://jsfiddle.net/Ezhb4/4/
i want to open a div in center of my screen ( horizontally and vertically).
var documnetWidth = $(document).width(),
documentHeight = $(document).height(),
widgetFormHeight = widgetForm.height(),
widgetFormWidth = widgetForm.width();
widgetForm.css({
top: documentHeight / 2 - widgetFormHeight / 2,
left: documnetWidth / 2 - widgetFormWidth / 2
});
my widget is coming horizontally center but vertically it takes some offset.
you can do this
define a size for the DIV and position Fixed, like this:
div {
position: fixed;
top: 50%;
left: 50%;
width: 200px;
height: 100px;
margin: -100px 0 0 -50px;
z-index: 99;
}
Or if you don't want to place it absolutly positioned, you can give it a width, and set it to:
div { margin: 0 auto; }
Try this:
documentHeight = $(window).height(),
instead of:
documentHeight = $(document).height(),
The way you had it you were getting the height of the document which could be more or less than the browser height.
And then to allow for how far the document is currently scrolled:
top: documentHeight/2-widgetFormHeight/2 + $(document).scrollTop(),
Demo: http://jsfiddle.net/vULHL/
Absolutely centered DIV without width or height:
http://jsfiddle.net/dFkXq/1/
And acts like a fixed element.