Responsive and Sticky Nav Bar - javascript

I have a nav bar that is fixed to the top of the page when the width is under 768px.
When it is over 768px it starts at the bottom and when the user scroll past it it become stuck to the top.
Both of these instance work fine on their own, but when the browser is resized there are some issues when going from under 768px to above. (Going from 768 to below works fine.)
When I load the page in a browser size under 768px and then resize the window above that is where I run in to problems.
I would like for the nav bar to smoothly transition between states. (It works beautifuly when loading above 768px then reszing to under and reszing above - Ideally this is how I would like it to work when loaded below 768px.) Or as an alternative just have the nav bar be fixed to the top when moving from under 768px to above.
This is the link to the site.
This is my CSS
.header{
width: 100%;
min-width: 300px;
height: 100px;
padding: 0px;
background: black;
position: absolute;
bottom: 0px;
z-index: 99999;
-webkit-font-smoothing: subpixel-antialiased;
}
.header.fixed{
width: 100%;
position: fixed;
top: 0px;
height: 100px;
-webkit-font-smoothing: subpixel-antialiased;
}
#media only screen and (max-width: 768px){
.header{
width: 100%;
background: black;
position: fixed;
top: 0px;
height: 100px;
-webkit-font-smoothing: subpixel-antialiased;
}
}
and this is the Javascript
<script>
jQuery(document).ready(function() {
var s = jQuery(".header");
var pos = s.position();
jQuery(window).scroll(function() {
var windowpos = jQuery(window).scrollTop();
if (windowpos >= pos.top) {
s.addClass("fixed");
} else {
s.removeClass("fixed");
}
});
});
</script>
I have also tried below to no luck.
<script>
if ( jQuery(window).width() > 768) {
jQuery(document).ready(function() {
var s = jQuery(".header");
var pos = s.position();
jQuery(window).scroll(function() {
var windowpos = jQuery(window).scrollTop();
if (windowpos >= pos.top) {
s.addClass("fixed");
} else {
s.removeClass("fixed");
}
});
});
}</script>
<script>
jQuery(window).resize(function(){
if ( jQuery(window).width() > 768) {
jQuery(document).ready(function() {
var s = jQuery(".header");
var pos = s.position();
jQuery(window).scroll(function() {
var windowpos = jQuery(window).scrollTop();
if (windowpos >= pos.top) {
s.addClass("fixed");
} else {
s.removeClass("fixed");
}
});
});
}})</script>

try this:
function sticky_navigation() {
var browserWidth = $(window).width();
var scroll_top = $(window).scrollTop(); // our current vertical position from the top
// if we've scrolled more than the page, change its position to fixed to stick to top,
// otherwise change it back to relative
if ((scroll_top > $('.header').height()) && (browserWidth > 720)) {
$('.header').css({ 'position': 'fixed', 'top':0, 'z-index':999999, 'opacity': 0.9, 'box-shadow': '0px 3px 5px #393939' });
} else {
$('.header').css({ 'position': 'relative', 'opacity': 1, 'box-shadow': 'none' });
}
};
// and run it again every time you scroll
$(window).scroll(function() {
sticky_navigation();
});
// and run every time you resize to boot
$(window).resize(function() {
sticky_navigation();
});

Related

Logo cloning on navbar scroll

I have the following script:
$(function() {
var header = $(".header-nav");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 50) {
header.addClass("scrolled");
}
if (scroll > 50 && scroll < 60) {
$(".header_logo img").clone().appendTo(".header-logo");
}
if (scroll <= 50) {
header.removeClass("scrolled");
}
});
});
It's supposed to make the navbar fixed on scroll and clone the website logo to the navbar on a .header-logo empty div
But it doesn't work as expected. The logo is mass duplicated or don't appear until a top scrolling.
Is there a way to make it work as: When I scroll, the logo is cloned one time on the navbar then disappear if you go back to top page?
Thanks
Clone img outside the condition, then append or remove based on your if condition. You need to set a class to detect cloned img for removing.
$(function() {
var header = $(".header-nav");
$el = $(".header-logo img").clone().addClass('cloned');
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 50) {
header.addClass("scrolled");
} else {
header.removeClass("scrolled");
}
if (scroll > 50) {
$el.appendTo(".header-logo");
} else {
$('.cloned').remove();
}
});
});
body {
height: 1000px;
/* fake height! */
}
header.header-nav.scrolled {
position: fixed;
}
.header-nav {
background: white;
width: 100%;
min-height: 150px;
border: 1px solid gray;
}
.scrolled {
background: red;
}
.header-logo img {
height: 150px;
display: block;
margin: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="header-nav">
<div class="header-logo">
<img src="https://i.graphicmama.com/blog/wp-content/uploads/2019/10/02145410/logo-design-trends-2020-colorful-gradient-logos-example-1.gif" />
</div>
</header>

Smooth transition on scroll after adding header on scroll up

I'm creating a header which:
Displays on default (transparent background)
When user scrolls down the page (25px), it will add the header--maroon class to header - which it does. The header-maroon class basically adds the background color and anchor styles.
But at this point (when the user has scrolled 25px down the page), I want the header to "fade up" smoothly and basically stay hidden when the user is scrolling down.
Lastly, when a user scrolls (10px) up the page, I want the header to fade in neatly at the top of the viewpoint.
Here's my current approach. It kind of works, but not as smooth as I'd like (as in the the header just appears, I want it to transition in). I have tried to add transitions, but it doesn't work?
/**********/
/* SCROLL */
/**********/
//Add transition when scrolling down
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 25) {
$("header").addClass("header--maroon");
} else {
$("header").removeClass("header--maroon");
}
});
// add scroll effect on page refresh too
$(function() {
var scroll = $(window).scrollTop();
if (scroll >= 10) {
$(".mainMenu").addClass("header--maroon");
} else {
$(".mainMenu").removeClass("header--maroon");
}
});
/******************************/
/* HIDE HEADER ON SCROLL DOWN */
/******************************/
var didScroll;
var lastScrollTop = 0;
var delta = 25;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
if(Math.abs(lastScrollTop - st) <= delta)
return;
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
body{
background: wheat;
height:1000px;
}
header {
position: fixed;
transition: top 0.2s ease-in-out;
width: 100%;
height: 90px;
background: transparent;
}
.nav-up {
top: -90px;
transition: top 0.2s ease-in-out;
}
.header--maroon {
background: #521717;
transition: top 0.2s ease-in-out;
}
.mainMenu {
background-color: transparent;
width: 100%;
padding: 10px 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="nav-down">
<div class="mainMenu">Link</div>
</header>
<div class="gap"></div>
Try implementing this:
JSFiddle
HTML:
<header class="nav-down">
This is your menu.
</header>
<main>
This is your body.
</main>
<footer>
This is your footer.
</footer>
CSS:
body {
padding-top: 40px;
}
header {
background: #f5b335;
height: 40px;
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -40px;
}
main {
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAPklEQVQYV2O8dOnSfwYg0NPTYwTRuAAj0QqxmYBNM1briFaIzRbi3UiRZ75uNgUHGbfvabgfsHqGaIXYPAMAD8wgC/DOrZ4AAAAASUVORK5CYII=) repeat;
height: 2000px;
}
footer { background: #ddd;}
* { color: transparent}
JS:
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
(** Credit for this code goes to the creator of the JSFiddle)
Hope this helps!
You can use the .animate() class.
Replace...
$('header').removeClass('nav-down').addClass('nav-up');
With...
$("header").animate({ top: '-90px' },300);
And replace...
$('header').removeClass('nav-up').addClass('nav-down');
With...
$("header").animate({ top: '10px' },300);
Here is a JSFiddle example using your code.
Note that this is just a rough implementation.
You can play with it and tweak it until it works as you want it to.
Add transition to the class which you are adding on scroll.
.header-maroon{
transition: all 0.5s ease-in-out;
}

Transparent navigation at top of page

I have the following code which adds/removes a class to my navigation div when the user scrolls.
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 100);
function hasScrolled() {
if ($(window).width() > 768) {
var st = $(this).scrollTop();
if (Math.abs(lastScrollTop - st) <= delta) {
return;
}
if (st > lastScrollTop && lastScrollTop >= 0 && st > 0) {
$('#anim-nav').removeClass('nav-down').addClass('nav-up');
} else {
$('#anim-nav').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
});
I want to add .trans-bg to #anim-nav when the user is close to the top of the screen. It has a background of white, but when it gets to the top o the screen I want it transparent as it goes over an image. However when i added it to this function wasn't reliable. Sometimes it would stay transparent, or not turn transparent.
Not sure how to add something that constantly runs to make sure if the user is near/at the top it applies.
Maybe this can help?
$(window).on('scroll', function () {
if ($(window).scrollTop() > 10) {
$('body').addClass('scrolled');
} else {
$('body').removeClass('scrolled');
}
});
body {
background: url("https://www.toptal.com/designers/subtlepatterns/patterns/christmas-black.png");
height: 3000px;
}
.scrolled .header {
background-color: rgba(255, 255, 255, .8)
}
.header {
background-color: #fff;
height: 80px;
position: fixed;
left: 0;
top: 0;
right: 0;
transition: .2s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="header"></header>
Solution: Listen to scroll changes instead of checking for scrolls at a interval.
Example of listening to scroll at top using javaScript:
window.addEventListener('scroll', function(e) {
if (document.body.scrollTop == 0) {
alert("top");
}
});

how to create a sliding menu which will fill the window width except by puller button width?

I am trying to create a sliding menu which will fill the window width minus the puller button width. I want the menu out of the window when web page load and there is a button which will go left when the page loads. When user clicks on the button the menu should come to window and button goes right.
I have created an animation video here which will show you what I want.
In the jsfiddle the menu just fades out, But I want the menu to slide from left to right when clicked on button with .puller class.
See the code at jsfiddle
Demo on jsfiddle
$(document).ready(function() {
var stickyNavTop = ($('.container')).offset().top;
var stickyNav = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyNavTop) {
$('.container').addClass('fixed');
} else {
$('.container').removeClass('fixed');
}
};
stickyNav();
$(window).scroll(function() {
stickyNav();
}).resize(function() {
stickyNav();
}).load(function() {
stickyNav();
});
$(".dropdown").click(function() {
$(".dpitem").slideToggle(300);
});
var calcWidth = function() {
var pullerDimensions = $('.puller').width();
$('#cpcc,.dpitem').width($(window).width() - pullerDimensions);
}
$(document).ready(function() {
calcWidth();
});
$(window).resize(function() {
calcWidth();
}).load(function() {
calcWidth();
});
var cPcc = document.getElementById ("cpcc");
var cpHeight = function() {
var cpBtnHolder = $(cPcc).height();
$('.content').css("padding-top",cpBtnHolder);
}
setInterval(function() {
cpHeight();
calcPHeight();
pp();
}, 0)
var calcPHeight = function() {
var toolsDimensions = $('#cpcc').height();
$('.puller').height(toolsDimensions);
$('.puller').css("line-height",toolsDimensions +"px");
}
$(document).ready(function() {
calcPHeight();
});
$(window).resize(function() {
calcPHeight();
}).load(function() {
calcPHeight();
});
var Pwidth = $('#cpcc').width();
var PSpce = $(window).width()-Pwidth;
$(".puller").click(function() {
$(".container").toggle( function() {
$(".container").css({
transform: "translate3d("+"-"+Pwidth+"px, 0, 0)"
});
}, function () {
$(".container").css({
transform: "translate3d(-0, 0, 0)"
});
});
});
});
Calc is your friend. You can use that along with 'transition' to achieve the intended effect. Check out this simplified example.
http://codepen.io/anon/pen/gPBQOb
Good practice is to toggle a class which will override the position property in this case left. It should also toggle your chevron image to point left and right.
Your example is using a lot of js calculations and has to recalculate with window size changes. This example uses js only to toggle a css class on click and the rest in managed purely with css. Much simpler in my opinion.
HTML
<div class="maincontent"></div>
<div class="menu">
<div class="button"></div>
</div>
CSS
.maincontent{
background-color: green;
height: 2000px;
width: 100%;
}
.menu{
background-color: red;
width: 100%;
height: 200px;
position: fixed;
top: 0px;
left: 0px;
transition: left 1s;
}
.menu.collapse{
left: calc(-100% + 30px)
}
.button{
background-color: yellow;
height: 100%;
width: 30px;
position: absolute;
right: 0px;
}
JS
$('.button').click(
function(){
$('.menu').toggleClass('collapse')
})

Fade in another logo on scroll

I'm currently swapping a logo for smaller logo when the user scrolls down the page. At the moment it's a straight swap. However I'd like to add a nice animated fade in/out so the larger logo fades out, smaller logo fades in and vice-versa.
Here's a pen of my current attempt: http://codepen.io/abbasinho/pen/yyomrB
I've tried to adding fadeIn but with not joy.
JS:
$(function() {
var logo = $(".lrg-logo");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
logo.removeClass('lrg-logo').addClass("sml-logo").fadeIn( "slow");
} else {
logo.removeClass("sml-logo").addClass('lrg-logo').fadeIn( "slow");
}
});
});
CSS:
.wrapper {
height: 2000px;
position: relative;
background: green;
}
header {
position: fixed;
width: 100%;
height: 50px;
background: grey;
}
.lrg-logo {
width: 300px;
height: 50px;
text-align: center;
background: red;
}
.sml-logo {
width: 200px;
height: 20px;
text-align: center;
background: red;
}
2 things:
logo must first be hidden in order to fade it in.
fade should not happen on every scroll event, but just once when scrolltop > 500
$(function() {
var logo = $(".lrg-logo");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
if(!logo.hasClass("sml-logo")) {
logo.hide();
logo.removeClass('lrg-logo').addClass("sml-logo").fadeIn( "slow");
}
} else {
if(!logo.hasClass("lrg-logo")) {
logo.hide();
logo.removeClass("sml-logo").addClass('lrg-logo').fadeIn( "slow");
}
}
});
});
Use this
$(function() {
var logo = $(".lrg-logo");
var scrolling = false;
var small = false;
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500 && !scrolling && !small) {
scrolling = true;
logo.fadeOut(300);
window.setTimeout(function() {
logo.fadeIn( 300).removeClass('lrg-logo').addClass("sml-logo");
scrolling = false;
small = true;
}, 300);
} else if(!scrolling && small) {
scrolling = true;
logo.fadeOut( 300);
window.setTimeout(function() {
logo.fadeIn( 300).removeClass('sml-logo').addClass("lrg-logo");
scrolling = false;
small = false;
}, 300);
}
});
});
I have two flags. One to see if its currently animating or not. Another one to check if its small or large.
http://codepen.io/anon/pen/jEGNbN
the code is in the link above

Categories