Change CSS property when an element reach a certain point - javascript

I have an image on a page that have a absolute position to be in the center of the page when it loads. When the user scroll down the page and the image reach a position of 20% from the top of the screen, I want to change the position of that image to fixed so it always stays on the screen at 20% from the top of the screen.
I guess that I will have to do something like this :
$(function () {
$(window).scroll(function () {
var aheight = $(window).height() / 2;
if ($(this).scrollTop() >= aheight) {
$("#image").css("position", "fixed");
}
else {
$("#image").css("position", "absolute");
}
});
});
This line is where I should put the 20% from top but I don't know how :
var aheight = $(window).height() / 2;
EDITED CODE (still not working but I forgot to post the var in my original post and the scroll height was set at 50% instead of 20%):
var t = $("#logo").offset().top;
$(function () {
$(window).scroll(function () {
var aheight = $(window).height() / 5;
if ($(this).scrollTop() >= aheight) {
$("#logo").css("position", "fixed");
}
else {
$("#logo").css("position", "absolute");
}
});
});
English is not my first language so I drew what I want to do in case my explanation was not clear :
Image of what I'm looking for
EDIT 2 (ANSWER) :
Stackoverflow won't let me answer my question because I don't have enough reputation so here is the working code I came with :
$(document).scroll(function(){
var bheight = $(window).height();
var percent = 0.3;
var hpercent = bheight * percent;
if($(this).scrollTop() > hpercent)
{
$('#logo').css({"position":"fixed","top":"20%"});
}else{
$('#logo').css({"position":"absolute","top":"50%"});
}
});

Check this fiddle.
http://jsfiddle.net/livibetter/HV9HM/
Javascript:
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top = $('#sticky-anchor').offset().top;
if (window_top > div_top) {
$('#sticky').addClass('stick');
} else {
$('#sticky').removeClass('stick');
}
}
$(function () {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
CSS:
#sticky {
padding: 0.5ex;
width: 600px;
background-color: #333;
color: #fff;
font-size: 2em;
border-radius: 0.5ex;
}
#sticky.stick {
position: fixed;
top: 0;
z-index: 10000;
border-radius: 0 0 0.5em 0.5em;
}
body {
margin: 1em;
}
p {
margin: 1em auto;
}

Alternatively, you can take a look at jquery-waypoints plugin. The use is as easy as:
$('#your-div').waypoint(function() {
console.log('25% from the top');
// logic when you are 25% from the top...
}, { offset: '25%' });

Related

Navbar hide on scroll with offset

I'm using this code to make my sticky navbar disappear on scroll down and re-appear on scroll up. However this code is pretty precise resulting sometimes in starting one of both animations without actually scrolling.
What I'm trying to achieve is that a user should scroll 20px down before the if statement runs. Same if they would scroll up again...
https://jsfiddle.net/as1tpbjw/2/
const body = document.querySelector("#navbar");;
let lastScroll = 0;
window.addEventListener("scroll", () => {
const currentScroll = window.pageYOffset;
if (currentScroll <= 0) {
body.classList.remove("scroll-up");
return;
}
if (currentScroll > lastScroll && !body.classList.contains("scroll-down")) {
body.classList.remove("scroll-up");
body.classList.add("scroll-down");
} else if (
currentScroll < lastScroll &&
body.classList.contains("scroll-down")
) {
body.classList.remove("scroll-down");
body.classList.add("scroll-up");
}
lastScroll = currentScroll;
});
As far as I can see, in my relatively old version of Firefox, it works well.
I added if (Math.abs(currentScroll - lastScroll) < 20) { return; } and this adds a 20px delay either way.
Also, that scroll-up class doesn't seem to be doing anything in the fiddle.
Update:
If you want an animation, you can replace the CSS for .scroll-down and add a transition to #navbar:
#navbar.scroll-down {
height: 0;
}
#navbar {
/* … */
transition: height .5s;
}
Not only does scroll-up do nothing, but the following code even breaks (doesn't show the navbar) when you scroll to the top:
if (currentScroll <= 0) {
body.classList.remove("scroll-up");
return;
}
You may want to remove it.
const body = document.querySelector("#navbar");
let lastScroll = 0;
window.addEventListener("scroll", () => {
const currentScroll = window.pageYOffset;
if (Math.abs(currentScroll - lastScroll) < 20) {
return;
}
if (currentScroll > lastScroll) {
body.classList.add("scroll-down");
} else {
body.classList.remove("scroll-down");
}
lastScroll = currentScroll;
});
body {
margin: 0;
min-height: 200vh;
}
#navbar.scroll-down {
height: 0;
}
#navbar {
height: 50px;
background: red;
position: sticky;
top: 0;
left: 0;
transition: height .5s;
}
<body>
<div id="navbar">
</div>
</body>

Back to top scroll var offset for different browser widths|heights

I implemented a "back to top" or "scroll to top" button in a WordPress site which works perfectly:
jQuery(document).ready(function($) {
var offset = 500;
var speed = 10;
var duration = 250;
$(window).scroll(function() {
if ($(this).scrollTop() < offset) {
$('.topbutton').fadeOut(duration);
} else {
$('.topbutton').fadeIn(duration);
}
});
$('.topbutton').on('click', function() {
$('html, body').animate({
scrollTop: 0
}, speed);
return false;
});
});
My dilemma is that I can't find a method to change the var offset to a flexible value according to browser width|height. Thus the narrower the browser/device screen, the further down the 500px trigger point occurs, causing the "back to top" button to appear too late. Here is my CSS:
.site-footer {
background-color: #0a0a0a;
}
.topbutton {
height: 100px;
width: 100px;
position: fixed;
right: 5px;
bottom: 5px;
z-index: 1;
background-image: url("https://sheknowsphotography.co.za/wp-content/uploads/2018/12/Arrow-up-blue-ezgif.com-resize.gif");
background-repeat: no-repeat;
display: none;
}
Here is the gif image inside the footer.php, just before the </body> tag:
<?php wp_footer(); ?>
<img src="https://sheknowsphotography.co.za/wp-content/uploads/2018/12/Arrow-up-blue-ezgif.com-resize.gif">
Everything is done in child theme.
To whoever responds: thank you for your time!
The solution that works:
jQuery(document).ready(function($){
if ($(window).width() < 960) {
var offset = 500;
}
else {
var offset = 1000;
}
var speed = 10;
var duration = 250;
$(window).scroll(function(){
if ($(this).scrollTop() < offset) {
$('.topbutton') .fadeOut(duration);
} else {
$('.topbutton') .fadeIn(duration);
}
});
$('.topbutton').on('click', function(){
$('html, body').animate({scrollTop:0}, speed);
return false;
});
});

How to animate element when you scroll down and then up

I have a problem with animation, when you start scrolling down the picture going with you until offset().top = 960px but when you scroll up this picture have to go with you to the top - and this is a problem then i don't know how to return it to the top. Here is my site, this animation on the top
//scroll cicada
var x = true;
$(window).scroll(function() {
var item = $("#cicada").offset().top;
var place = $("#circles").offset().top;
if (item >= 950 && x) {
$("#cicada").css("position", "absolute");
$("#cicada").css("top", "950px");
x = false;
} else if (item <= 950 && !x) {
$("#cicada").css("top", "160px");
x = true;
}
});
css:
.cicada {
width: 340px;
height: 380px;
background: url("../includes/images/main-item-min.png") no-repeat center center;
background-size: contain;
position: fixed;
z-index: 5;
top: 160px;
right: 59%;
z-index: 8888;
}
I guess, you should make your header visible only, when you are at top of your scroll i.e. when currentTop is 0.
var currentTop = $(window).scrollTop();
if (currentTop == 0) {
$("header").css("display", "block");
} else {
$("header").css("display", "none");
if ($('.menu').hasClass("change")) {
$('.menu').removeClass("change");
}
}
I hope, It will help.

jQuery: Sticky navigation bar changes margins

I've a navigation bar that moves when page scrolls, this is jQuery:
$(document).ready(function() {
var stickyNavTop = $('.nav').offset().top;
var stickyNav = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyNavTop) {
$('.nav').addClass('sticky');
} else {
$('.nav').removeClass('sticky');
}
};
stickyNav();
$(window).scroll(function() {
stickyNav();
});
});
And CSS
.sticky {
position: fixed;
width: 100%;
left: 0;
top: 0;
border-top: 0;
}
The problem is that when the navigation bar position gets fixed, the main content under the navigation bar rearrange the margin because it thinks that the navigation bar has been removed but I don't want this, I want my boxes stay in their places.
What should I do?
Here is jsfiddle:
https://jsfiddle.net/omidh/cvjt0eLL/6/
This workaround keeps your markup as it is, with minimal edits to the jQuery and CSS, see the demo and code below.
DEMO: https://jsfiddle.net/cvjt0eLL/10/
Added CSS:
.push {
margin-top: 50px; /*same height as navbar*/
}
Updated jQuery:
$(document).ready(function () {
var stickyNavTop = $('.nav').offset().top;
var stickyNav = function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyNavTop) {
$('.nav').addClass('sticky');
$('.content').addClass('push'); // added
} else {
$('.nav').removeClass('sticky');
$('.content').removeClass('push'); //added
}
};
stickyNav();
$(window).scroll(function () {
stickyNav();
});
});

Bug with elastic scrolling and menu bar in JS

I want to set up a menu bar like you see her in JSfiddle:
http://jsfiddle.net/gvjeyywa/21/
There it works exactly the way I want it to … But on the webpage it has a bug, I think it's because of the elastic scrolling in OSX … On scrolling down the menu bar should slide in from the top to set up on top:0px, being fixed there… But if you scroll back to top and the elastic scrolling scrolls higher than the body is… the menu jumps too high…
Here see the live example:
http://www.cyrill-kuhlmann.de/index.php/projects
on iOS it's a complete mess too…
Here is the JS Code:
var bitFlag = false;
var isActive = true;
var lastScrollTop = 0;
var timeoutId;
$navigation = $("#navigation");
$(window).scroll(function (event) {
var intWindowTop = $(window).scrollTop();
var intElementBottom = $navigation.offset().top + $navigation.height();
if (intWindowTop > lastScrollTop) {
isActive = true;
if (!bitFlag) {
$navigation.css("position", "absolute").css("top", intWindowTop + "px");
bitFlag = true;
}
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function () {
if (intWindowTop > intElementBottom) {
intDelayTime = setTimeout(function () {
if (isActive) {
$navigation.animate({ top: intWindowTop + "px" }, {
duration: 800,
step: function () {
if ($(window).scrollTop() < $navigation.offset().top) {
$(this).stop(true,true);
}
},
complete: function () {
intDelayTime2 = setTimeout(function () {
$("#navigation").css("position", "fixed").css("top", "0px");
bitFlag = false;
isActive = false;
}, 1);
}
});
}
}, 500);
}
}, 100);
} else {
$navigation.css("position", "fixed").css("top", "0px");
bitFlag = false;
isActive = false;
}
lastScrollTop = intWindowTop;
});
And this is the CSS:
#navigation {
position:absolute;
top: 0px;
left: 0px;
right: 0px;
height: 80px;
background-color: #FFF;
z-index:999;
padding-top: 25px;
padding-left: 45px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
Does someone have an idea? Unfortunately I'am a bloody starter in JS… I am thankful for any help…
problem is this: intWindowTop > lastScrollTop.
this value is true, when you scroll into the negative area, that comes with webkit.
so you have to check, if the value is positive via intWindowTop > 0
$(window).scroll(function () {
var intWindowTop = $(window).scrollTop();
var intElementBottom = $navigation.offset().top + $navigation.height();
if ( intWindowTop > lastScrollTop && intWindowTop > 0 ) {
//...
} else {
//...
}
note that i removed the variable "event" as well. you dont use it, so why declare it..?

Categories