I found this jsfiddle here at stackoverflow, but the solution provided by the person is very jumpy. http://jsfiddle.net/BramVanroy/ZVzEe/ I need something very smooth.
var secondary = $("#secondary-footer");
secondary.hide().addClass("fixed").fadeIn("fast");
$(window).scroll(function() {
if (secondary.offset().top >= ($(document).height() - 350)) {
secondary.removeClass("fixed");
}
else if(secondary + ":not('.fixed')") {
secondary.addClass("fixed");
}
});
How I need the sticky footer to work is for it to show the footer as a narrow bar at the bottom of the page while still scrolling through the content. Once the bottom of the page is reached with the scrollbar, the footer will expand in height.
The jsfiddle provided is very close to how I need this to work, but I need something very smooth. And another note, the height of the fully expanded footer is not fixed. Thanks to everyone for your help.
demo
jQuery
var secondary = $("#secondary-footer");
secondary.hide().addClass("fixed").fadeIn("fast");
$(window).scroll(function() {
var scrollBottom = $(window).scrollTop() + $(window).height();
$("#content").css("bottom",secondary.height());
var maxHeight = 350; // set maximum height of the footer here
var minHeight = 120; // set the minimum height of the footer here
secondary.height(maxHeight - ($(document).height() - scrollBottom));
if (secondary.height() <= minHeight) secondary.height(minHeight);
});
CSS
#content {
width: 90%;
margin: 0 auto;
padding: 0.5em;
background: #dedede;
position:relative; /* added this */
}
#secondary-footer {
width: 100%;
height: 120px;
background: #666;
position: fixed;
bottom: 0;
left: 0;
}
/* removed #secondary-footer.fixed and merged content with #secondary-footer */
Another solution: http://jsfiddle.net/27rNu/
jQuery
$(document).ready(function() {
var secondary = $("#secondary-footer");
secondary.addClass("fixed");
var windowH = $('#wrapper').outerHeight(true);
$(window).scroll(function() {
var scrollVal = $(this).scrollTop();
if (scrollVal < (windowH - 350 * 2)) {
secondary.addClass("fixed");
}
else {
secondary.removeClass("fixed");
}
});
});
I also added a "wrapper" div around the whole html.
Related
I have this problem which is probable very simple to solve, but I'm a newbie with JS/JQuery.
I have this code (see fiddle here: https://jsfiddle.net/Tiph/6ep3hp4j/) where my div footer shows when the scroll gets at the bottom of the document, but I want it to show when the scroll gets at a certain height under my header and have a fixed position at the bottom of my window. I understand that I have to calculate something with window.height, and/of offsetTop, but nothing works.
Someone can help me with it?
Thank you so much! :-)
my code here:
var footer = $('#footer'),
extra = 10;
footer.css({ opacity: '0', display: 'block' });
$(window).scroll(function() {
var scrolledLength = ( $(window).height() + extra ) + $(window).scrollTop(),
documentHeight = $(document).height();
console.log( 'Scroll length: ' + scrolledLength + ' Document height: ' + documentHeight )
if( scrolledLength >= documentHeight ) {
footer
.addClass('bottom')
.stop().animate({ bottom: '0', opacity: '1' }, 300);
}
else if ( scrolledLength <= documentHeight && footer.hasClass('bottom') ) {
footer
.removeClass('bottom')
.stop().animate({ bottom: '-100', opacity: '0' }, 300);
}
});
I create new sample code for you to understand how its work
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(window).scroll(function() {
var count=700;
var menuHeight = $('#footer').height()+count;
var top = $(this).scrollTop();
var bottom = $(document).height() - $(this).height() - $(this).scrollTop();
if (bottom < menuHeight) {
$('#footer').removeClass( 'top' );
$('#footer').addClass( 'bottom' );
$('#footer').fadeIn( 'slow' );
}
else {
$('#footer').fadeOut( 'slow' );
}
});
});
</script>
<meta charset="utf-8">
</head>
<body>
<style>
#footer{
width: 100%;
height: 60px;
background-color: #cccccc;
vertical-align: middle;
text-align: center;
font-size:3em;
}
.bottom{
position: fixed;
bottom: 0;
left: 0;
z-index: 999;
display:block;
}
</style>
<div style="height:2000px;"></div>
<div id="footer" style="display:none" > This is your footer</div>
<div style="height:700px"></div>
Try to change the number 700 to set where you want to footer to be shown
Say you want the header to show when you have scrolled 100px from the top.
You can do something like:
$(window).on("scroll", function() {
if(document.body.scrollTop >= 100) {
$("#footer").fadeIn()
} else {
$("#footer").fadeOut()
}
});
Say, you want to only show the header if a button with id, callToAction is above the viewport, you can do:
$(window).on("scroll", function() {
if(document.getElementById('callToAction').getBoundingClientRect().top <= 0) {
$("#footer").fadeIn()
} else {
$("#footer").fadeOut()
}
});
This code var y = $(this).scrollTop(); get your scroll height from top.
$(window).scroll(function() {
var y = $(this).scrollTop();
if (y > 800) { // scroll gets at a certain height
$('.bottomDiv').fadeIn();
} else {
$('.bottomDiv').fadeOut();
}
});
If I correctly understand your question you need to change documentHeight with value what you want.
Example: documentHeight = 150; not documentHeight = $(document).height();
It is good idea to rename documentHeight variable.
My website at the moment has three sections in a single scroll layout. With a Heading for two sections: About & Contact (these are div boxes) that animate when you scroll to the bottom of the page. What I'm trying to achieve is having the animation take place when the user scrolls down and hits the bottom of each (div box) section as opposed to the bottom of the website.
I believe I need to implement the .offset() function but unsure if that is correct?
Any help would be greatly appreciated.
CSS
.header {
display: none;
position: relative;
left: 0px;
right: 0px;
top: 500px;
height: 80px;
width: 100%;
background:red;
color: #fff;
text-align: center;
}
JS
var header = $('.header'),
extra = 10; // In case you want to trigger it a bit sooner than exactly at the bottom.
header.css({ opacity: '0', display: 'block' });
$(window).scroll(function() {
var scrolledLength = ( $(window).height() +extra) + $(window).scrollTop(),
documentHeight = $(document).height();
console.log( 'Scroll length: ' + scrolledLength + ' Document height: ' + documentHeight )
if( scrolledLength >= documentHeight ) {
header
.addClass('top')
.stop().animate({ top: '20', opacity: '1' }, 800);
}
else if ( scrolledLength <= documentHeight && header.hasClass('top') ) {
header
.removeClass('top')
.stop().animate({ top: '500', opacity: '0' }, 800);
}
});
Fiddle - http://jsfiddle.net/SFPpf/480/
Looks like position() would be better in this case. The position method is relative to the document whereas offset is relative to the parent element. It returns an object with the properties "top" and "left". It can only return the position of one element at a time, so for the first div, you would need to use first() and eq() to get a specific one.
The bottom of a .fillWindow will be its vertical position + its height.
var $fillWindow = $(".fillWindow").first(), // or eq() for others
position = $fillWindow.position(),
height = $fillWindow.height();
//bottom = position.top + height;
scrollTop() can now be used to check when the user scrolls past the .fillWindow.
if ( $(window).scrollTop() >= position.top ) {
// do the animation here
} else {
// do something else
}
Edit: I just caught my mistake. It should be $(window).scrollTop(). You should also just test for scrollTop being at the top of the .fillWindow.
It's easy to keep a column in my layout fixed so it's always visible, even when the user scrolls down.
It's also easy to only move the column down the page when the page is scrolled down far enough for it to be out of the viewport so it's anchored before scrolling starts.
My problem is, I have left hand column that is taller than the average window so you need to be able to scroll down to see all the content (controls) in the left column but at the same time when you scroll up you want to see the top of the controls again.
Here's a visual of what I want to accomplish:
So the left column is always occupying 100% of the height of the window but as the user scrolls down they can see the bottom of the div, and when they start to scroll up the scrolls up until it reaches the top of the window again. So no matter how far they scroll the page, the top of the div is always nearby.
Is there some jQuery magic to make this happen?
Did you mean something like this? (Demo)
var sidebar = document.getElementById('sidebar');
var sidebarScroll = 0;
var lastScroll = 0;
var topMargin = sidebar.offsetTop;
sidebar.style.bottom = 'auto';
function update() {
var delta = window.scrollY - lastScroll;
sidebarScroll += delta;
lastScroll = window.scrollY;
if(sidebarScroll < 0) {
sidebarScroll = 0;
} else if(sidebarScroll > sidebar.scrollHeight - window.innerHeight + topMargin * 2) {
sidebarScroll = sidebar.scrollHeight - window.innerHeight + topMargin * 2;
}
sidebar.style.marginTop = -sidebarScroll + 'px';
}
document.addEventListener('scroll', update);
window.addEventListener('resize', update);
#sidebar {
background-color: #003;
bottom: 1em;
color: white;
left: 1%;
overflow: auto;
padding: 1em;
position: fixed;
right: 80%;
top: 1em;
}
body {
line-height: 1.6;
margin: 1em;
margin-left: 21%;
}
It almost degrades gracefully, too…
I made a fiddle for you, hope this helps you out abit.
I detect scroll up or scroll down, and set the fixed position accordion to the direction.
http://jsfiddle.net/8eruY/
CSS
aside {
position:fixed;
height:140%;
background-color:red;
width:100px;
top:20px;
left:20px;
}
Javascript
//Detect user scroll down or scroll up in jQuery
var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel" //FF doesn't recognize mousewheel as of FF3.x
$('html').bind(mousewheelevt, function(e){
var evt = window.event || e //equalize event object
evt = evt.originalEvent ? evt.originalEvent : evt; //convert to originalEvent if possible
var delta = evt.detail ? evt.detail*(-40) : evt.wheelDelta //check for detail first, because it is used by Opera and FF
if(delta > 0) {
$('aside').css('top', '20px');
$('aside').css('bottom', 'auto');
}
else{
$('aside').css('bottom', '20px');
$('aside').css('top', 'auto');
}
});
http://jsfiddle.net/KCrFe/
or this:
.top-aligned {
position: fixed;
top: 10px;
}
with
var scrollPos
$(window).scroll(function(event){
var pos = $(this).scrollTop();
if ( pos < scrollPos){
$('.sidebar').addClass('top-aligned');
} else {
$('.sidebar').removeClass('top-aligned');
}
scrollPos = pos;
});
Hi I got this code from another question and it works great. The only problem that I have is that there is padding-top added to the header I am using it on. I would like the padding to decrease along with the height to the point where there is no padding, I don't know how to add that attribute to this code. Can someone help? I would like them to decrease at the same rate so the content stays centered vertically.
the initial padding-top is set to this padding: 40px 0 0;
here is the jquery
var header = $('#main'),
headerH = header.height();
$(window).scroll(function() {
if ($(this).scrollTop() <= headerH / 2) {
header.css({
height: -($(this).scrollTop() - headerH)
});
} else {
header.css({
height: headerH / 2
});
}
}).scroll();
here is the question i got the initial jquery from: Shrink header height by scrollTop value
What about this one? DEMO http://jsfiddle.net/yeyene/xaDLy/1/
You can maintain css properties easily.
var header = $('#main'),
headerH = header.height();
$(window).scroll(function() {
if ($(this).scrollTop() > 100) {
header.stop().animate({
padding: '10px 0px 10px 0px'
}, 300);
} else {
header.stop().animate({
padding: '40px 0 40px 0'
}, 300);
}
});
I have implemented a parallax scrolling effect based on a tutorial I found. The effect works great. However, when I specify the background images, I am unable to control the y (vertical) axis. This is causing problems because I'm trying to set locations on multiple layered images.
Any thoughts on what's causing the problem?
Here is one external script:
$(document).ready(function(){
$('#nav').localScroll(800);
//.parallax(xPosition, speedFactor, outerHeight) options:
//xPosition - Horizontal position of the element
//inertia - speed to move relative to vertical scroll. Example: 0.1 is one tenth the speed of scrolling, 2 is twice the speed of scrolling
//outerHeight (true/false) - Whether or not jQuery should use it's outerHeight option to determine when a section is in the viewport
$('#mainimagewrapper').parallax("50%", 1.3);
$('#secondaryimagewrapper').parallax("50%", 0.5);
$('.image2').parallax("50%", -0.1);
$('#aboutwrapper').parallax("50%", 1.7);
$('.image4').parallax("50%", 1.5);
})
This is another external script:
(function( $ ){
var $window = $(window);
var windowHeight = $window.height();
$window.resize(function () {
windowHeight = $window.height();
});
$.fn.parallax = function(xpos, speedFactor, outerHeight) {
var $this = $(this);
var getHeight;
var firstTop;
var paddingTop = 0;
//get the starting position of each element to have parallax applied to it
$this.each(function(){
firstTop = $this.offset().top;
});
if (outerHeight) {
getHeight = function(jqo) {
return jqo.outerHeight(true);
};
} else {
getHeight = function(jqo) {
return jqo.height();
};
}
// setup defaults if arguments aren't specified
if (arguments.length < 1 || xpos === null) xpos = "50%";
if (arguments.length < 2 || speedFactor === null) speedFactor = 0.1;
if (arguments.length < 3 || outerHeight === null) outerHeight = true;
// function to be called whenever the window is scrolled or resized
function update(){
var pos = $window.scrollTop();
$this.each(function(){
var $element = $(this);
var top = $element.offset().top;
var height = getHeight($element);
// Check if totally above or totally below viewport
if (top + height < pos || top > pos + windowHeight) {
return;
}
$this.css('backgroundPosition', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px");
});
}
$window.bind('scroll', update).resize(update);
update();
};
})(jQuery);
Here is the CSS for one section:
#aboutwrapper {
background-image: url(../images/polaroid.png);
background-position: 50% 0;
background-repeat: no-repeat;
background-attachment: fixed;
color: white;
height: 500px;
width: 100%;
margin: 0 auto;
padding: 0;
}
#aboutwrapper .image4 {
background: url(../images/polaroid2.png) 50% 0 no-repeat fixed;
height: 500px;
width: 100%;
margin: 0 auto;
padding: 0;
}
.image3{
margin: 0 auto;
min-width: 970px;
overflow: auto;
width: 970px;
}
Both of these are being called to achieve the parallax scrolling. I really just want to more specifically control the background image locations. I've tried messing with the CSS background position and I've messed with the first javascript snippet as well. No luck.
just a quick shot, have you tried actually placing the images, either in a div or just using the img src tag to actually move the element rather than manipulating the y axis of a background image?