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();
});
});
Related
I made this snippet code to hide menu on scroll down and show on scroll up but I have some issues, when I scroll to top the menu still have fixed position, how I can resolve this problem, Thanks!
JAVSCRIPT :
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
});
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('.mainmenu').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 500);
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
$('.mainmenu').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('.mainmenu').removeClass('nav-up');
}
}
lastScrollTop = st;
}
CSS :
.mainmenu {
background: #222;
height: 50px;
padding: 0 15px;
width: 80%;
margin: 0 auto;
}
.nav-down{
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
Demo : jsfiddle
To you first listener, just add an else statement as follows:
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 150)
$('.mainmenu').addClass('nav-down');
else
$('.mainmenu').removeClass('nav-down');
});
Also note that you don't need a setInterval() for the second listener, see jsfiddle
I tested it and it works fine!!
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
else
{
$('.mainmenu').removeClass('nav-down');
}
});
Add an else to your scrollTop with a removeClass and you should be fine, I tested it and it works. Here
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
else
{
$('.mainmenu').removeClass('nav-down');
}
});
Detect nav direction with a variable
var lastscrolltop=0;
jQuery(window).bind('scroll', function () {
if (jQuery(window).scrollTop() > lastscrolltop)
jQuery('.mainmenu').addClass('nav-up');
else
jQuery('.mainmenu').removeClass('nav-up');
lastscrolltop=jQuery(window).scrollTop();
});
and use css transition for a smooth show/hide
.mainmenu {
transition:all 0.5s ;
}
Your way is too much complicated.
You can hide the menu on scroll with a simple transition using jQuery .fadeIn() and fadeOut(), without the need for css.
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
$('.mainmenu').fadeOut('fast');
} else {
$('.mainmenu').fadeIn('fast');
}
lastScrollTop = st;
});
So I basically want the script to start at the top of "mini" div but can't get it to work right.
#mini {
width: 100%;
padding-top: 300px;}
var tTop = $("#mini").outerHeight(true);
Full script:
$(window).scroll(checkY);
function checkY() {
//save this value so we dont have to call the function everytime
var top = $(window).scrollTop();
$(".title").each(function () {
var target = $(this).closest(".content");
var tTop = $("#mini").outerHeight(true);
var tBottom = target.offset().top + target.outerHeight();
if (top >= tTop && top <= tBottom) {
console.log("Show");
$(this).show();
} else {
console.log("Hide");
$(this).hide();
}
});
}
checkY();
Why not setting the mini style to
position:relative;
and the inner div to
position: absolute;
top:0
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%' });
I am trying to make a menu that sticks to the bottom of the page and then to the top after scrolling. The only problem is that instead of scrolling with the page, the menu stays in the same place and then jumps to the top right at the end.
I am running stellar.js on the site also and I wondered if this was conflicting but I removed the calling javascript and the problem persisted so I put it back.
The site URL is www.percolatedpropaganda.co.uk
I am stumped and any help would be much appreciated!
Javascript
$(document).ready(function() {
var windowH = $(window).height();
var stickToBot = windowH - $('#menu').outerHeight(true);
$('#menu').css({'top': stickToBot + 'px'});
$(window).scroll(function() {
var scrollVal = $(this).scrollTop();
if ( scrollVal > stickToBot ) {
$('#menu').css({'position':'fixed','top' :'0px'});
} else {
$('#menu').css({'position':'absolute','top': stickToBot +'px'});
}
});
});
CSS
#menu {
font-size: 85%;
position: relative;
float: left;
}
Why don't you try this:
Javascript:
$(document).ready(function() {
$(window).scroll(function() {
var scrollVal = $(this).scrollTop();
if ( scrollVal > 0 ) {
$('#menu').css({bottom: '', top :'0px'});
} else {
$('#menu').css({top: '', bottom: '0px'});
}
});
});
CSS:
#menu {
position: fixed;
bottom: 0;
}
Check it out: Example
UPDATE:
If you want the movement to be animated use this instead:
Javascript:
$(document).ready(function() {
var menu = $('#menu');
var windowH = $(window).height();
var stickToBot = windowH - menu.outerHeight(true);
menu.css('top', stickToBot + 'px');
$(window).scroll(function() {
var scrollVal = $(this).scrollTop();
if ( scrollVal > 0 ) {
menu.stop().animate({top :'0px'});
} else {
menu.stop().animate({top: stickToBot + 'px'});
}
});
});
CSS:
#menu {
position: fixed;
}
Have a look: Example
UPDATE 2:
If you want it like cwtchcamping.co.uk... have a look at this:
Javascript:
$(document).ready(function() {
var menu = $('#menu');
var windowH = $(window).height();
var stickToBot = windowH - menu.outerHeight(true);
menu.css('top', stickToBot + 'px');
$(window).scroll(function() {
var scrollVal = $(this).scrollTop();
if (scrollVal > stickToBot) {
menu.css({top: '0px', position: 'fixed'});
}
else {
menu.css({top: stickToBot + 'px', position: 'absolute'});
}
});
});
CSS:
#menu {
position: absolute;
}
Example: JSFiddle
I wonder how to make a sticky header shrink(with animation) when you scroll down the page and goes back to normal state when the page is scrolled up to the top. Here are two examples to clearify:
http://themenectar.com/demo/salient/
http://www.kriesi.at/themes/enfold/
I get the part to make it fixed, but how should I do to shrink my header when the user scrolls down?
Thanks a ton
This should be what you are looking for using jQuery.
$(function(){
$('#header_nav').data('size','big');
});
$(window).scroll(function(){
if($(document).scrollTop() > 0)
{
if($('#header_nav').data('size') == 'big')
{
$('#header_nav').data('size','small');
$('#header_nav').stop().animate({
height:'40px'
},600);
}
}
else
{
if($('#header_nav').data('size') == 'small')
{
$('#header_nav').data('size','big');
$('#header_nav').stop().animate({
height:'100px'
},600);
}
}
});
Demonstration:
http://jsfiddle.net/jezzipin/JJ8Jc/
Here a CSS animation fork of jezzipin's Solution, to seperate code from styling.
JS:
$(window).on("scroll touchmove", function () {
$('#header_nav').toggleClass('tiny', $(document).scrollTop() > 0);
});
CSS:
.header {
width:100%;
height:100px;
background: #26b;
color: #fff;
position:fixed;
top:0;
left:0;
transition: height 500ms, background 500ms;
}
.header.tiny {
height:40px;
background: #aaa;
}
http://jsfiddle.net/sinky/S8Fnq/
On scroll/touchmove the css class "tiny" is set to "#header_nav" if "$(document).scrollTop()" is greater than 0.
CSS transition attribute animates the "height" and "background" attribute nicely.
http://callmenick.com/2014/02/18/create-an-animated-resizing-header-on-scroll/
This link has a great tutorial with source code that you can play with, showing how to make elements within the header smaller as well as the header itself.
Based on twitter scroll trouble (http://ejohn.org/blog/learning-from-twitter/).
Here is my solution, throttling the js scroll event (usefull for mobile devices)
JS:
$(function() {
var $document, didScroll, offset;
offset = $('.menu').position().top;
$document = $(document);
didScroll = false;
$(window).on('scroll touchmove', function() {
return didScroll = true;
});
return setInterval(function() {
if (didScroll) {
$('.menu').toggleClass('fixed', $document.scrollTop() > offset);
return didScroll = false;
}
}, 250);
});
CSS:
.menu {
background: pink;
top: 5px;
}
.fixed {
width: 100%;
position: fixed;
top: 0;
}
HTML:
<div class="menu">MENU FIXED ON TOP</div>
http://codepen.io/anon/pen/BgqHw
I did an upgraded version of jezzipin's answer (and I'm animating padding top instead of height but you still get the point.
/**
* ResizeHeaderOnScroll
*
* #constructor
*/
var ResizeHeaderOnScroll = function()
{
this.protocol = window.location.protocol;
this.domain = window.location.host;
};
ResizeHeaderOnScroll.prototype.init = function()
{
if($(document).scrollTop() > 0)
{
$('header').data('size','big');
} else {
$('header').data('size','small');
}
ResizeHeaderOnScroll.prototype.checkScrolling();
$(window).scroll(function(){
ResizeHeaderOnScroll.prototype.checkScrolling();
});
};
ResizeHeaderOnScroll.prototype.checkScrolling = function()
{
if($(document).scrollTop() > 0)
{
if($('header').data('size') == 'big')
{
$('header').data('size','small');
$('header').stop().animate({
paddingTop:'1em',
paddingBottom:'1em'
},200);
}
}
else
{
if($('header').data('size') == 'small')
{
$('header').data('size','big');
$('header').stop().animate({
paddingTop:'3em'
},200);
}
}
}
$(document).ready(function(){
var resizeHeaderOnScroll = new ResizeHeaderOnScroll();
resizeHeaderOnScroll.init()
})
I took Jezzipin's answer and made it so that if you are scrolled when you refresh the page, the correct size applies. Also removed some stuff that isn't necessarily needed.
function sizer() {
if($(document).scrollTop() > 0) {
$('#header_nav').stop().animate({
height:'40px'
},600);
} else {
$('#header_nav').stop().animate({
height:'100px'
},600);
}
}
$(window).scroll(function(){
sizer();
});
sizer();