Reducing fixed header on scroll from top of page - javascript

I have a website with a fixed header, on the home page the header contains additional content when you are at the top of the page, but I want to hide this content and have a reduced header as they scroll down the page.
So on the initial scroll i want to hide the additional header content and animate the margin of the content below but keep it so that the top of the content still shows underneath it and then scroll from normal from there.
The snippet below should show what I mean better:
var head_height = $('#header').outerHeight(true);
$('#page_content').css('margin-top', (head_height)+'px');
if($('#extra_header_content').length != 0){
$('#header').addClass('home');
var main_head_height = $("#main_header_content").outerHeight(true);
var extra_head_height = $('#header').outerHeight(true);
$(document).on("scroll", function(){
if($(document).scrollTop() >= main_head_height){
$("#extra_header_content").slideUp("slow");
$('#page_content').css('margin-top', (main_head_height)+'px');
$('#header').removeClass('home');
}else{
$("#extra_header_content").slideDown("slow");
$('#page_content').css('margin-top', (extra_head_height)+'px');
$('#header').addClass('home');
}
});
}else{
$('#header').removeClass('home');
}
div{padding:0px;margin:0px;}
#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}
#main_header_content{height:50px;width:100%;}
#extra_header_content{height:50px;width:100%;}
#page_content{background-color:#33d;height:5000px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
<div id="main_header_content">Main header</div>
<div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>

You need to change in your JS code. Margin you are reducing when the page start scrolling need to adjust by padding. So you can try this:
var head_height = $('#header').outerHeight(true);
$('#page_content').css('margin-top', (head_height)+'px');
if($('#extra_header_content').length != 0){
$('#header').addClass('home');
var main_head_height = $("#main_header_content").outerHeight(true);
var extra_head_height = $('#header').outerHeight(true);
$(document).on("scroll", function(){
if($(document).scrollTop() >= main_head_height){
$("#extra_header_content").slideUp("slow");
// $('#page_content').css('margin-top', (main_head_height)+'px');
$('#page_content').css(
{'margin-top': (main_head_height)+'px', 'padding-top': (main_head_height)+'px'}
);
$('#header').removeClass('home');
}else{
$("#extra_header_content").slideDown("slow");
$('#page_content').css('margin-top', (extra_head_height)+'px');
$('#header').addClass('home');
}
});
}else{
$('#header').removeClass('home');
}
div{padding:0px;margin:0px;}
#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}
#main_header_content{height:50px;width:100%;}
#extra_header_content{height:50px;width:100%;}
#page_content{background-color:#33d;height:5000px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
<div id="main_header_content">Main header</div>
<div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>

You can do it like this:
var head_height = $('#header').outerHeight(true);
$('#page_content').css('margin-top', (head_height)+'px');
if($('#extra_header_content').length != 0){
$('#header').addClass('home');
var main_head_height = $("#main_header_content").outerHeight(true);
var extra_head_height = $('#extra_header_content').outerHeight(true);
$(document).on("scroll", function() {
const scrollTop = $(document).scrollTop();
if (scrollTop >= head_height) {
$("#extra_header_content").css('height', 0);
$('#page_content').css('margin-top', main_head_height);
$('#header').removeClass('home');
} else if (scrollTop > 0) {
$("#extra_header_content").css('height', extra_head_height - scrollTop);
$('#page_content').css('margin-top', head_height);
$('#header').removeClass('home');
} else {
$("#extra_header_content").css('height', extra_head_height);
$('#page_content').css('margin-top', head_height);
$('#header').addClass('home');
}
});
}else{
$('#header').removeClass('home');
}
div{padding:0px;margin:0px;}
#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}
#main_header_content{height:100px;width:100%;}
#extra_header_content{height:100px;width:100%; overflow: hidden;}
#page_content{background-color:#33d;height:500px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
<div id="main_header_content">Main header</div>
<div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>

I can offer you a different approach without JavaScript
body,html{
padding:0;
margin:0;
}
#main-header{
position:fixed;
top:0;
left:0;
right:0;
height: 50px;
background: green;
z-index:3;
}
#extra-header{
position:fixed;
top:50px;
left:0;
right:0;
height: 50px;
background: lime;
z-index: 0;
}
#content{
margin-top:100px;
height:2000px;
position:relative;
z-index:1;
background:blue;
}
#content>div{
height:200px;
background: #efefef;
}
#content>div:nth-of-type(2n){
background: red;
}
<div id="main-header">
Main
</div>
<div id="extra-header">
Extra
</div>
<div id="content">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

This could be a solution if you will use position sticky and not fixed, but this a bit jerky, So I will post one more solution here with smooth animation
var head_height = $('#header').outerHeight(true);
//$('#page_content').css('padding-top', (head_height)+'px');
if ($('#extra_header_content').length != 0) {
$('#header').addClass('home');
var main_head_height = $("#main_header_content").outerHeight(true);
var extra_head_height = $('#header').outerHeight(true);
$(document).on("scroll", function() {
if ($(document).scrollTop() >= main_head_height) {
$('#page_content').css('padding-top', (main_head_height) + 'px');
$("#extra_header_content").slideUp("slow");
//$('.page_content_wrapper').addClass('scrolled');
//$('.page_content_wrapper').css('top', (main_head_height)+'px');
$('#header').removeClass('home');
} else {
$("#extra_header_content").slideDown("slow");
$('#page_content').css('padding-top', 0);
//$('.page_content_wrapper').css('top', 0);
//$('#header').addClass('home');
}
});
} else {
$('#header').removeClass('home');
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
div {
padding: 0px;
margin: 0px;
}
#header {
background-color: #d33;
position: sticky;
top: 0px;
width: 100%;
z-index: 9;
}
.home {
background-color: #3d3 !important;
}
#main_header_content {
height: 50px;
width: 100%;
}
#extra_header_content {
height: 50px;
width: 100%;
}
#page_content {
background-color: #33d;
height: 5000px;
width: 100%;
}
.page_content_wrapper {
position: relative;
top: 0px;
}
#page_content .page_content_wrapper {
transition: top 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
<div id="main_header_content">Main header</div>
<div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">
<div class="page_content_wrapper">This should still be visible when header initially reduces</div>
</div>
<span class="hamBurger"></span>

Related

I've got a js appear effect issue

This is js and there is 4 articles should appear one at a time when I scroll down, but it doesn't work after aticle no.2. what did I wrong?
function scrollAppear(){
var main = document.querySelector("main");
var art = main.querySelectorAll("article");
var artPos1 = art[0].getBoundingClientRect().top;
var artPos2 = art[1].getBoundingClientRect().top;
var artPos3 = art[2].getBoundingClientRect().top;
var artPos4 = art[3].getBoundingClientRect().top;
var artPos5 = art[4].getBoundingClientRect().top;
var screenPos = window.innerHeight /1.3;
if (artPos1>600 && artPos1<700) {
art[0].classList.add('appear');
}
else if (artPos2<500) {
art[1].classList.add('appear');
}
else if (artPos3<800) {
art[2].classList.add('appear');
}
else if (artPos4<600) {
art[3].classList.add('appear');
}
else if (artPos5<600) {
art[4].classList.add('appear');
}
}
window.addEventListener('scroll',scrollAppear);
If they all need to appear at the same spot, shouldn't the same condition work for each?
if (artPos1>600 && artPos1<700) {
art[0].classList.add('appear');
}
else if (artPos2>600 && artPos2<700) {
art[1].classList.add('appear');
}
else if (artPos3>600 && artPos3<700) {
art[2].classList.add('appear');
}
else if (artPos4>600 && artPos4<700) {
art[3].classList.add('appear');
}
else if (artPos5>600 && artPos5<700) {
art[4].classList.add('appear');
}
Consider the following jQuery example.
function scrollAppear() {
var main = $("#main");
var art = $("article");
var screenPos = $(window).scrollTop();
art.each(function(i, el) {
if (screenPos >= $(el).css("top").slice(0, -2) - 120) {
$(el).fadeIn(100).addClass("appear");
}
});
}
window.addEventListener('scroll', scrollAppear);
#main {
position: relative;
height: 2000px;
}
article {
width: 100%;
height: 100px;
position: absolute;
display: none;
}
.red {
background: #F00;
top: 600px;
}
.orange {
background: #F60;
top: 700px;
}
.yellow {
background: #FF0;
top: 800px;
}
.green {
background: #0F0;
top: 900px;
}
.blue {
background: #00F;
top: 1000px;
}
.purple {
background: #F0F;
top: 1100px;
}
.appear {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main">
<article class="red">
</article>
<article class="orange">
</article>
<article class="yellow">
</article>
<article class="green">
</article>
<article class="blue">
</article>
<article class="purple">
</article>
</div>
You can use .scrollTop():
Get the current vertical position of the scroll bar for the first element in the set of matched elements or set the vertical position of the scroll bar for every matched element.
https://api.jquery.com/scrolltop/
Use .each() to iterate over each element and make it appear if scrolling has crossed the proper threshold on the screen.

Show/hide div on scroll with JQuery WordPress

I have a div with a social bar at the bottom of the screen on my site but I want to display it only after the user scrolls a little and hide it once the user is about to reach the footer. So around 200px before the page ends.+
This is my div:
<div class="sticky-bar-hr">
.......
</div>
This is my CSS:
.sticky-bar-hr{
display: none;
}
And this is the JQuery I am trying:
<script>
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 800) {
$('.sticky-bar-hr').fadeOut();
} else {
$('.sticky-bar-hr').fadeIn();
}
});
</script>
But it does not work. The problem seems to be that the function is not being called. I am setting the script in my homepage HTML in Wordpress
Any help?
Thanks in advance
Try this
$(window).scroll(function() {
var y = $(this).scrollTop();
if(y<200) {
$('.sticky-bar-hr').fadeOut();
}
if (y > 200) {
$('.sticky-bar-hr').fadeIn();
}
if(y+ $(this).height() == $(document).height()) {
$('.sticky-bar-hr').fadeOut();
}
});
body {
height: 2000px;
}
.sticky-bar-hr {
position:fixed;
bottom: 0;
width: 100%;
height: 50px;
background:#000;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sticky-bar-hr">
This is because you have inverted fadeIn and fadeOut.
Here is a working snippet:
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 800) {
$('.sticky-bar-hr').fadeOut();
} else {
$('.sticky-bar-hr').fadeIn();
}
});
.sticky-bar-hr{
display: none;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 30px;
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sticky-bar-hr">
.......
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

jQuery calculate the number of line breaks in a div?

So I have a div wrap whose size is a percentage of the screen width. Inside this wrap is multiple .item divs. As the window gets smaller it breaks into new lines obviously.
I wrote some code which basically takes the width of the wrap and divides it by the sum of the widths of the .item boxes. But the flaw is that it looks at it thinking how many boxes could fit in total, were one to mix and match them perfectly like building blocks, but that's not how it works because the ordering is stagnant.
How could I make this logic work?
CodePen
jQuery:
var itemWidth = 0;
var lineCount = 1;
$(window).on('resize', function(){
var lineWidth = $('.line').width();
var itemWidthSum = 0;
lineCount=1;
$('.item').each(function(index, element) {
if(itemWidthSum < (lineWidth - $(element).outerWidth())) {
itemWidthSum = itemWidthSum + $(element).outerWidth();
} else {
lineCount++;
itemWidthSum = 0;
}
});
});
HTML:
<div id="container">
<div class="rect">
<div class="line">
</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
</div>
<h1 class="answer"></h1>
CSS:
body {
padding:25px;
}
.answer {
position:fixed;
bottom:0;
left:0;
}
#container {
border: 1px solid rgb(200,200,200);
height: auto;
width: 30%;
margin:0 auto;
}
.item {
padding: 10px;
background-color: #aef2bd;
float: left;
}
.rect {
height: 100px;
width:100%;
position: relative;
}
.rect .line {
position:absolute;
height:50px;
width: 100%;
bottom:0;
border-top: 1px solid red;
}
Figured out my logic mistake by debugging each step.
The correct jQuery:
var itemWidth = 0;
var lineCount = 1;
$(window).on('resize', function(){
var lineWidth = $('.line').width();
var itemWidthSum = 0;
var list = [];
lineCount=1;
$('.item').each(function(index, element) {
if((lineWidth - itemWidthSum) > ($(element).outerWidth())) {
itemWidthSum = itemWidthSum + $(element).outerWidth();
} else {
lineCount++;
itemWidthSum = $(element).outerWidth();
}
});
});

Next / previous arrows to cycle through divs

I want to add two arrows to the sides of the "boxes" divs (below) to cycle through the 3 divs.
Working JSFiddle: https://jsfiddle.net/HBHcC/11/
Can someone help me with this?
HTML:
<div class="container">
<div class="boxes">
<div class="one box">
</div>
<div class="two box">
</div>
<div class="three box">
</div>
</div>
</div>
CSS:
.container{
width:100px;
height:100px;
overflow:hidden;
position:relative;
}
.box {
display:inline-block;
float: left;
width: 100px;
height: 100px;
}
.one{
background-color:green;
}
.two{
background-color:red;
}
.three{
background-color:blue;
}
.boxes{
width:400px;
}
JS:
$(document).ready(function(){
$('.box').on("click", function() {
// Is this the last div, or is there a next one?
if ($(this).next().length) {
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
}
});
});
After adding arrows to the div, here is a new fiddle that should get you started:
$('.rightarrow').on("click", function() {
// Is this the last div, or is there a next one?
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
});
$('.leftarrow').on("click", function() {
// Is this the last div, or is there a next one?
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "+=100"}, animSpeed);
});
https://jsfiddle.net/tx2yg06w/1/
Updated w/arrows moved out of divs:
$(document).ready(function(){
var animSpeed = 200;
$('.rightarrow').on("click", function() {
if(parseInt($("#boxes").css("marginLeft")) == -200){ return;}
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
});
$('.leftarrow').on("click", function() {
if(parseInt($("#boxes").css("marginLeft")) == 0){ return;}
$('.boxes').animate({marginLeft : "+=100"}, animSpeed);
});
});
https://jsfiddle.net/b56r0d72/
Errata has given you a good solution. Just wire up his code to the arrows in the snippet below.
Run snippet to view:
<html>
<body>
<style type="text/css">
.leftarrow, .rightarrow {
font-size: 48px;
color: blue;
text-decoration: none;
}
.rightarrow {
color: red;
float: right;
}
.content {
width: 200px;
padding: 4px;
border: 1px gray solid;
}
.box {
height: 200px;
border: 1px green solid;
}
</style>
<div class="content">
<div>
◀
▶
</div>
<div class="box">slide</div>
</div>
</body>
</html>

Slide to next div

HTML:
<div class="inline-wrapper">
<div class="inline-blocks" id="f">123</div>
<div class="inline-blocks" id="s">123</div>
<div class="inline-blocks" id="t">123</div>
<div class="inline-blocks" id="fo">123</div>
</div>
CSS:
html, body {
width: 100%;
height: 100%;
/* overflow: hidden;*/
}
.inline-wrapper{
width: 400%;
height: 100%;
font-size: 0;
position: relative;
}
.inline-blocks{
display: inline-block;
width: 25%;
height: 100%;
vertical-align: top;
position: relative;
}
>.inline-blocks:nth-child(1){
background-color: #000;
}
.inline-blocks:nth-child(2){
background-color: blue;
}
.inline-blocks:nth-child(3){
background-color: red;
}
.inline-blocks:nth-child(4){
background-color: green;
}
How can I slide them without ID?
In fact this is the work of the slider. But I can not understand the logic.
Want to understand how flipping without ID.
We must check the blocks and give them сurrent class.
Auto Slide
HTML:
<div class="inline-wrapper">
<div class="inline-blocks" id="f">123</div>
<div class="inline-blocks" id="s">123</div>
<div class="inline-blocks" id="t">123</div>
<div class="inline-blocks" id="fo">123</div>
</div>
jQuery:
(function () {
var numDivs = $('.inline-wrapper').children().length; //Count children ELements
var counter = 1;
function slide(time, counter) {
var $currentDiv = $('.inline-wrapper .inline-blocks:nth-child(' + counter + ')'); //get next element
var position = $currentDiv.position(); //get position of next element
if (numDivs > 1) {
$('html,body').animate({
scrollLeft: position.left
}, time / 2); //Animate to next element
}
};
$('.inline-blocks').on('click', function () {
counter = counter + 1;
slide(2000, counter);
});
})();
DEMO

Categories

Resources