Changing header color when scroll with javascript - javascript

I've tried searching for a solution for a while.
So it starts transparent and then as I scroll a certain length it changes to have a background color. The code below is what I have so far
CSS File
header {
padding-top: 10px;
background-color: transparent;
color: white;
position: fixed;
width: 100%;
z-index: 1;
}
.changeColor {
background-color: rgba(30, 32, 35, 0.9);
}
JS in script tags at the bottom of the HTML file
var scroll_distance = 100;
var transparent = true;
document.addEventListener("scroll", function(){
if($(document).scrollTop() > scroll_distance ) {
if(transparent) {
transparent = false;
$('header').removeClass('changeColor');
}
} else {
if( !transparent ) {
transparent = true;
$('header').addClass('changeColor');
}
}
});
window.addEventListener("scroll", function(){
if($(document).scrollTop() > scroll_distance ) {
if(transparent) {
transparent = false;
$('header').removeClass('changeColor');
}
} else {
if( !transparent ) {
transparent = true;
$('header').addClass('changeColor');
}
}
});
HTML file
<header id="headernavbar">
...
</header>
Any tips on how to go about doing this? I tried using JQuery as well but same results. It doesn't add the class at all. I also cleared cookies and cache before visiting the site and tried multiple browsers with no luck. I was also going to add transition effects after I fixed this issue.

You got it opposite. There's no error but the logic error.
By default your background is already trasparent.
You've set on scroll from top, to remove that class when its not even added.
What you need to fix?
When the document_scrolltop > scroll_distance, you add the class, else remove it.
var scroll_distance = 100;
var transparent = true;
document.addEventListener("scroll", function() {
if ($(document).scrollTop() > scroll_distance) {
if (transparent) {
transparent = false;
$('header').addClass('changeColor');
}
} else {
if (!transparent) {
transparent = true;
$('header').removeClass('changeColor');
}
}
});
header {
padding-top: 10px;
background-color: transparent;
color: black;
position: fixed;
border:2px solid;
width: 100%;
z-index: 1;
}
.changeColor {
background-color: rgba(30, 32, 35, 0.9);
transition: all 0.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header id="headernavbar">
...
</header>
RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANRANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>DOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>RANDOMSTUFF<br>

Perhaps you could simplify the code, you can see it working if you paste it in the console of the developer tools
window.addEventListener('scroll', function(e) {
let headerColor = (window.scrollY) > 100 ? 'red' : 'blue';
console.log(headerColor);
});

Related

Nav Bar Scroll Function NOT Working

What I need to do to change the colour of my nav bar when I scroll down by a certain amount and reset when I scroll back up. I have tried many different techniques. AKA youtube videos on the subject. But cannot seem to get it to work! I have a 'scrolled' class in my CSS stylesheet with a background color set. But it won't even take my function.
$(function(){
$(window).scroll(function() {
if($(window).scrollTop() >= 100) {
$('.nav').addClass('scrolled');
}else {
$('.nav').removeClass('scrolled');
}
});
});
Google Chrome Dev-Files
//$(function(){
$(window).scroll(function() {
if($(window).scrollTop() >= 100) {
$('.nav').addClass('scrolled');
}else {
$('.nav').removeClass('scrolled');
}
});
//});
.nav {
max-width: 500px;
height: 1000px;
}
.nav.scrolled {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav">
</div>
THANKS SO MUCH!
Not sure what the outermost $(function() {... does, but I think that was the reason the snippet inside did not run.
//$(function(){
$(window).scroll(function() {
if($(window).scrollTop() >= 100) {
$('.nav').addClass('scrolled');
}else {
$('.nav').removeClass('scrolled');
}
});
//});
.nav {
max-width: 500px;
height: 1000px;
}
.nav.scrolled {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav">
</div>
If you intended to use IIFE, immediately invoked function expression, you can do
(function(){
$(window).scroll(function() {
if($(window).scrollTop() >= 100) {
$('.nav').addClass('scrolled');
}else {
$('.nav').removeClass('scrolled');
}
});
}());
which also works.
This describes how to implement this in Vanilla JS, also taking care of performance using passive event listeners.
Codepen Links
let navRef = document.querySelector('nav');
document.addEventListener('scroll', () => {
if (window.scrollY > 500) {
navRef.classList.add('scrolled');
} else {
navRef.classList.remove('scrolled');
}
}, { passive: true })
body {
margin: 0;
}
div.container {
background: aliceblue;
height: 10000px;
}
nav {
height: 50px;
background: pink;
position: fixed;
width: 100vw;
transition: background 0.3s ease-in-out;
}
nav.scrolled {
background: #80deea;
}
<div class="container">
<nav></nav>
</div>

Img resize on scroll

How can i resize a logo( es width: 100px ) in a header on mouse scrolling?
$('.logo').scroll(function() {
$(this).width(100);
$(this).off(); //removes the handler so that it only resizes once...
})
.header {
background-color: black;
}
.logo {
height:100px;
width: 100%;
background-image: url("http://unika.myarmah.it/skin/frontend/sns_simo/default/images/logo.png");
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header">
<div class="logo"></div>
</div>
Just use javascript:
Why? - Because its just as short as using jQuery.
Update #1 -
after seeing the comments to the previous answer from the author, I have adjusted my example to include animation and reset when at the top of the page. Again - just use javascript, and for better performance benefits use CSS classes so that all paints are done in one cycle.
Update #1 jsfiddle - https://jsfiddle.net/113dn29z/16/
var logo = document.querySelector('.logo');
var handleResize = function(e) {
if (document.body.scrollTop === 0) {
logo.classList.remove("resize");
} else {
logo.classList.add("resize");
}
};
document.addEventListener('scroll', handleResize);
<div class="header">
<div class="logo">
</div>
</div>
body {
height: 9999px;
overflow: auto;
}
.header {
background-color: black;
}
.logo {
margin-top: 200px;
height:100px;
width: 100%;
background-color: red;
background-repeat: no-repeat;
transition: width 0.2s ease;
}
.logo.resize {
width: 100px;
}
old jsFiddle example - https://jsfiddle.net/113dn29z/10/
var logoHasResized = false;
$(document).on('scroll', function (e) {
if (window.scrollY == 0) {
$('.logo').animate({'width': '100%'}, 250);
logoHasResized = false;
} else if (logoHasResized == false) {
$('.logo').animate({'width': 100}, 250);
logoHasResized = true;
}
});
edit: Since you want it to go back when you scroll to the top of the page, i've added in a check to see if the animation has happened, as you don't want it to fire constantly.

after scrolling, detect when element returns to original position

I am trying to, sort of, emulate the effect here. Essentially, during scrolling, change the css (drop shadow), and when the element comes back to original position (remove shadow).
I am able to detect scroll, but not able to figure out how to detect the return to the original un-scrolled state.
HTML
<div id="container">
<ul>
<li id="one">el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li>
</ul>
</div>
CSS
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#container {
height: 100px;
width: 500px;
border: 1px solid #000000;
overflow: scroll;
}
JS (with jquery)
var p = $('#one');
var position0 = p.position().top;
$('#container').scroll(function () {
if (p.position().top != position0) {
console.log('p.position: ' + p.position().top);
$('#container').css('background-color', 'pink');
}
});
JSFIDDLE: http://jsfiddle.net/nrao89m3/
PS: From console.log it doesn't seem to return to its original value at all.
Just add an else block:
var p = $('#one');
var position0 = p.position().top;
$('#container').scroll(function () {
if (p.position().top != position0) {
console.log('p.position: ' + p.position().top);
$('#container').css('background-color', 'pink');
} else {
$('#container').css('background-color', 'white');
}
});
http://jsfiddle.net/vyjbwne2/

Responsive Horizontal Scrolling Menu

http://healthunit.com has a clean horizontal scrolling menu at the top of the screen once you view it from a mobile phone device. I'm trying to mimic that same exact functionality thanks to a site I'm redesigning with a huge level of navigation elements.
Requirements:
Left and right scroll click options
Centered list item option centered in the space
Only one list item visible at a time
Horizontal Scrolling & Responsive
Clicking the last or first option in the list will take you to either the first option or last option in the list
My current html for this section is:
<nav id="sub" class="clearfix">
<ul class="wrapper">
<li>Estimate</li>
<li>About</li>
<li>Customer Information</li>
<li>Financing</li>
<li>Careers</li>
<li>Locate Us</li>
<li>Inspiration</li>
</ul>
</nav>
The CSS currently attached to it is:
nav#sub {
background: #004173;
background: linear-gradient(to bottom, #004173 0%,#014f8d 100%);
background: -moz-linear-gradient(top, #004173 0%, #014f8d 100%);
background: -ms-linear-gradient(top, #004173 0%,#014f8d 100%);
background: -o-linear-gradient(top, #004173 0%,#014f8d 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#004173), color-stop(100%,#014f8d));
background: -webkit-linear-gradient(top, #004173 0%,#014f8d 100%);
border-bottom: #00325a solid 3px;
box-shadow: 0 4px 6px 0 #BFBFBF;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#004173', endColorstr='#014f8d',GradientType=0 );
webkit-box-shadow: 0 4px 6px 0 #BFBFBF;
}
#sub ul {
text-align: center;
}
#sub ul li {
padding: 10px 3.3%;
}
#sub a {
color: #fff;
font-size: 10pt;
font-weight: 400;
text-decoration: none;
}
#sub ul a:hover li {
background: #007FEB;
}
So, finally I think I have what you are looking for:
Fiddle: http://jsfiddle.net/fzXMg/2/
CSS and HTML is in the Fiddle...
JS:
$(function(){
var state = 0;
var maxState = 6;
var winWidth = $(window).width();
$(window).resize(function(){
winWidth = $(window).width();
$('.box,.container_element').width(winWidth-100);
}).trigger('resize');
$('#lefty').click(function(){
if (state==0) {
state = maxState;
} else {
state--;
}
$('.container_element').animate({scrollLeft:((winWidth-100)*state)+'px'}, 800);
});
$('#righty').click(function(){
if (state==maxState) {
state = 0;
} else {
state++;
}
$('.container_element').animate({scrollLeft:((winWidth-100)*state)+'px'}, 800);
});
});
This uses jQuery again.
Now that the healthunit site has changed the original question is not completely clear.
To make a nav menu that scrolls horizontally uses arrow buttons (instead of scrollbar) can be implemented with a little jQuery and easily converted to pure JavaScript.
var $bar = $('.nav');
var $container = $('#outer');
var widths = {};
var scrollOffset = 0;
var container = document.getElementById("outer");
var bar = document.getElementById("bar");
function setMetrics() {
metrics = {
bar: bar.scrollWidth||0,
container: container.clientWidth||0,
left: parseInt(bar.offsetLeft),
getHidden() {
return (this.bar+this.left)-this.container
}
}
updateArrows();
}
function doSlide(direction){
setMetrics();
var pos = metrics.left;
if (direction==="right") {
amountToScroll = -(Math.abs(pos) + Math.min(metrics.getHidden(), metrics.container));
}
else {
amountToScroll = Math.min(0, (metrics.container + pos));
}
$bar.css("left", amountToScroll);
setTimeout(function(){
setMetrics();
},400)
}
function updateArrows() {
if (metrics.getHidden() === 0) {
$(".toggleRight").addClass("text-light");
}
else {
$(".toggleRight").removeClass("text-light");
}
if (metrics.left === 0) {
$(".toggleLeft").addClass("text-light");
}
else {
$(".toggleLeft").removeClass("text-light");
}
}
function adjust(){
$bar.css("left", 0);
setMetrics();
}
$(".toggleRight").click(function(){
doSlide("right");
});
$(".toggleLeft").click(function(){
doSlide("left");
});
$(window).on("resize",function(){
// reset to left pos 0 on window resize
adjust();
});
setMetrics();
Demo: https://www.codeply.com/go/HgAVBVfQFY
Check out that fiddle: http://jsfiddle.net/zEPQ5/15/
It's not perfect in meaning of design, but it shows off the concept.
I used jQuery with that.
$(function(){
var state = 0;
$('#up').click(function(){
state += 1;
$('ul.wrapper').animate({marginTop:(15-state*35)+'px'},400);
});
$('#down').click(function(){
state -= 1;
$('ul.wrapper').animate({marginTop:(15-state*35)+'px'},400);
});
});
Check out this jsfiddle: http://jsfiddle.net/7vvdB/
Basically, create an outer container with a max-width of 100% and a overflow-x:scroll, then create an inner container with a fixed width large enough to fit all of your elements, then put all of your elements in the inner container.
.container_element
{ white-space:nowrap
min-width:100%;
overflow-x:scroll;
overflow-y:hide;
}
.inner_container
{
width:5000px;
}
}

Making a sticky header work

I've got the following code for a sticky header, but I can't get the scroll to work and it's not a smooth transition. The #top-nav-wrapper barely scrolls when the fixed header below is activated:
<script>
$(document).scroll( function() {
var value = $(this).scrollTop();
if ( value > 48 ) {
$(".header").css("position", "fixed");
$("body").css("padding-top", "90px");
} else {
$(".header").css("position", "relative");
$("body").css("padding-top", "0");
}
});
</script>
The 48 value is the height of the #top-nav-wrapper, plus it has a box-shadow.
The .header class with the search bar is what should remain.
The basic html:
<div class="headerWrapper">
<div id="top-nav-wrapper"></div>
<div class="header"></div>
</div>
The CSS:
body {
background: #EEE;
}
#top-nav-wrapper {
width: 100%;
position: relative;
box-shadow: 0px 1px 1px 0px #B8B8B8;
z-index: 2001;
background: #EEE;
}
.header {
position: relative;
left: 0;
top: 0;
width: 100%;
min-height: 90px;
z-index: 2000;
background: #EEE;
height: 90px;
box-shadow: 0px 1px 2px #C4C4C4;
}
* I tried the following suggestion, but it's the same effect as before:
<script>
$(window).scroll( function() {
var value = $(this).scrollTop();
var $body = $('body');
var docked = $body.hasClass('docked');
if ( value > 48 ) {
if( !docked ) {
$body.addClass('docked');
}
} else {
if( docked ) {
$body.removeClass('docked');
}
}
});
</script>
Any ideas appreciated.
Update - I've changed the script to the following and placed it in the head - this resolves the top nav not scrolling dynamically and I added a placeholder div after the header and before the content with the same size height as the fixed header to keep the content where it should be (because the fixed header changes the natural flow), but there's still the lag/jump when the fixed header kicks in.
Placeholder CSS:
.headerPlaceholder {
height: 90px;
width: 100%;
display: none;
}
Solution to top nav not scrolling all the way after 48px scroll height was set:
<script>
$(document).ready(function () {
var div = $('.header');
var div2 = $('.headerPlaceholder');
var start = $(div).offset().top;
$.event.add(window, "scroll", function () {
var p = $(window).scrollTop();
$(div).css('position', ((p) > start) ? 'fixed' : 'static');
$(div).css('top', ((p) > start) ? '0px' : '');
$(div2).css('display', ((p) > start) ? 'block' : 'none');
});
});
</script>
To make it a smooth transition, there might need to be a slight delay and fadein/out effect, if anyone could help with that?
You can try
$(window).scroll( function() {
var value = $(this).scrollTop();
var $body = $('body');
var docked = $body.hasClass('docked');
if ( value > 48 ) {
if( !docked ) {
$body.addClass('docked');
}
} else {
if( docked ) {
$body.removeClass('docked');
}
}
});
CSS
.docked {
padding-top: 90px;
}
.docked .header {
position: fixed;
z-index: 2005;
}
You can be more efficient if there is an overall container you can target instead of body.

Categories

Resources