jQuery positioning footer without element the jump - javascript

So I am using jQuery to position the footer absolutely on pages where there isnt much content.
The problem I have noticed is that the footer loads in it's normally position and then visibily jumps to the bottom of the page when the jQuery adds the class. Is there anyway to get around this jump?
/* Position footer bottom of all pages */
positionFooter: function () {
var windowHeight = jQuery(window).height();
var content = jQuery("#content").height() + jQuery("#footer-wrapper").height();
if (windowHeight > content){
jQuery("#content").css("padding-bottom", jQuery("#footer-wrapper").height());
jQuery("#footer-wrapper").addClass("fixed-bottom");
}
}
I am using window.load:
jQuery(window).load(function()

How about this
positionFooter: function ()
{
var windowHeight = jQuery(window).height();
var content = jQuery("#content").height() + jQuery("#footer-wrapper").height();
jQuery("#footer-wrapper").addClass("fixed-bottom");
jQuery("#footer-wrapper").hide();
if (windowHeight > content)
{
jQuery("#content").css("padding-bottom", jQuery("#footer-wrapper").height());
jQuery("#footer-wrapper").show();
}
}

If you can change the html, maybe you should use a css sticky footer
http://ryanfait.com/sticky-footer/
I've used this in a lot of websites and works just fine

A quick dirty fix would be to give the body { opacity: 0} before the document loads, and then animate the opacity back up to 1 over a period of, say, 1 second. That way, the whole body will fade in after the footer has already jumped.
simple fiddle
This is how a lot of people deal with Flashes Of Unstyled Content (or FOUC).
Edit: As Freeeeez pointed out below, using body as the animatee isn't necessary, but in my opinion the effect is pleasing :)

If you set it to display:none as default with a specific class. You could then use jQuery to remove the class after the document has finished loading with something like this:
$(document).ready(function(){
$('.hideMe').removeClass('hideMe');
});

Related

Fixing JS sticky header glitch

There are a few posts on this already, and one answer that addresses the glitch I'm experiencing but the fix doesn't work with my setup.
(Existing Post 1)
(Existing Post 2)
-
I've used some JS to create a div that sticks to the top of the browser window when a user scrolls past it. The setup works by applying the class .sticky to the existing parent container #stickywrapperaa when a user scrolls past the parent element. Here is the JS:
<script>
jQuery(document).ready(function( $ ) {
// Cache selectors outside callback for performance.
var $window = $(window),
$stickyEl = $('#stickywrapperaa'),
elTop = $stickyEl.offset().top;
$window.scroll(function() {
$stickyEl.toggleClass('sticky', $window.scrollTop() > elTop);
});
});
</script>
This creates the element ID/class attribute of #stickywrapperaa.sticky which I have then positioned and styled using CSS. All of this so far is working.
The problem:
The problem I have is that when the sticky header is activated this removes a section of the page height and causes the static page content to jump up by the same height as the parent container (#stickywrapperaa).
Logically this makes perfect sense as the container has been moved ontop of the static page content so it's now missing from the page content; however this leaves a gaping hole in my page that I now need to fill.
I thought about creating an empty space of equal height to the parent container (#stickywrapperaa) and triggering that to appear with the sticky class, effectively replacing where the header used to be with an empty space.
Can anyone help me achieve this or provide a better solution?
Add a padding-top to body when you toggle the sticky class. The padding should be the same height as your header.
<script>
jQuery(document).ready(function( $ ) {
// Cache selectors outside callback for performance.
var $window = $(window),
$stickyEl = $('#stickywrapperaa'),
elTop = $stickyEl.offset().top;
$window.scroll(function() {
$stickyEl.toggleClass('sticky', $window.scrollTop() > elTop);
if ($window.scrollTop() > elTop){
$("body").css("padding-top", $stickyEl.height());
} else {
$("body").css("padding-top", 0);
}
});
});
</script>
Set the position of the div that gets removed to absolute, while creating another, invisible div that is set to relative, and has the same height as the absolute div.
Although adding in the div with the height later might work, it would overly complicate things when you could just put it there in the first place, and remove the visible div from the normal flow.

JavaScript replace content by sliding more content in without losing height

So i currently have a setup that allows for a button to be pressed, the current content is hidden, and more content scrolls in from the right. However my problem is that for the briefest of moments the footer, which sits below the content, moves up before moving back down below the content just loaded in.
This fiddle best illustrates the problem: http://jsfiddle.net/9Dubr/766/
My Code:
$('#rightButton').click(function(){
var toLoad = 'page.html #content';
$('#content').hide("fast", loadContent);
function loadContent() {
$('#content').load(toLoad,'',showNewContent);
}
function showNewContent() {
$('#content').show("slide", {direction: "right" }, 1000 );
}
return false;
});
Thanks for your help
The fiddle doesn't seem to work for me, but it sounds to me like your footer is simply trying to occupy the empty space left behind by the previous content. In which case, you can try giving the parent container of your content a fixed height just before hiding it. You can then unset the height once the next content is loaded, that way there isn't really any empty space for the footer to try and occupy.
Untested code:
$('#content').parent().css({height: $('#content').height()});
$('#content').hide("fast", loadContent);
...
function showNewContent() {
$('#content').show("slide", {direction: "right", complete: function() {
$('#content').parent().css({height: ''});
} }, 1000 );
}
If you'd like to make it more visually appealing, you can animate the height so the footer will get pushed/pulled more smoothly.
Hope this helps.
It may be because the page is allowed to resize the lengths of divs. A few suggestions that might work is:
Quick Fixes:
Hiding your footer until the person is at the bottom of the screen
Making your footer a static size and maybe even making the footer position final.
Adding a fixed size container around your objects as mentioned in a previous comment.
This way atleast it won;t bother the footer in any way.
Fix without changing footer:
It is obviously a load problem when the button itself is pressed. Because as I understand from your code when the button is pressed and then you are adding this new content to your page right before using the slide effect.
I would suggest you preload the content when first opening the page and then just use the .slide() when the button is pressed.

How can I improve this sticky footer code & fix one minor issue?

For some reason you need to drag the window in jsfiddle to get it going, but it works fine onLoad in context.
The idea behind this is that if the content exceeds the height of the window, it will removeClass ".sticky" which is slamming the footer down absolute to the bottom of the page. Otherwise, it's a sticky footer.
It should be pretty elegant. My issue is that for a moment, the footer clips off the content. I want it to removeClass ".sticky" when the aqua background of the section[role="main"] meets the footer's purple background and not a pixel later. I can't seem to get this going.
The footer is always the same height... can I just subtract it from something?
$(document).ready(function(){
$('aside[role="sidebar"]').height($(window).height());
if( $('section[role="main"]').height() >= $(window).height() ) {
$('.footer').removeClass('sticky');
}
$(window).resize(function(){
$('aside[role="sidebar"]').height($(window).height());
if( $('section[role="main"]').height() <= $(window).height() ) {
$('.footer').addClass('sticky');
}
else {
$('.footer').removeClass('sticky');
}
});
});
Working example here:
http://jsfiddle.net/LxvQ9/ make sure to resize to get it going initallly. Again, this is some issue with jsFiddle. Works fine on my site onLoad.
Thanks for any help.
While calculating height of any element, we also need to consider padding and border if any.
In jQuery we use outerHeight to get the height of any element including padding and border.
So, in your case, we are using only height and that's why some text is clipping.
Use the following code to properly calculate the height and update the footer class.
JavaScript Code
$(function(){
//When Window is Resized
$(window).resize(makeFooterSticky);
//Run once on page load
mkaeFooterSticky();
});
function makeFooterSticky() {
$('aside[role="sidebar"]').height($(window).height());
if( $('section[role="main"]').outerHeight() <= $(window).height() - $('.footer').outerHeight() ) {
$('.footer').addClass('sticky');
} else {
$('.footer').removeClass('sticky');
}
}
Hope this should work.
Let me know if there are any issues.
JSFiddle Demo : http://jsfiddle.net/hVzat/3/

jQuery Lazy load for animated scrolling

I would like to use Lazy load to my site, but there is a little problem: I scroll the content with JS (animate the content with X px ), so I don't use the scrollbars. Sadly, lazy load doesn't trigger in this case. Got any ideas how to make this?
My site scrolling horizontally, all content div-s float near each other and only the current one is visible, all other are on display: none;
Here is a not so pro pic of my site: I marked with black the visible area and with red, the moving parts.
my site in pic
All I can think of is hook into when the content slides, then add the images in or the whole content with AJAX if thats your aim. Plugins will usually focus on the majority of use cases, so Lazy load might not be good for you.
I would just write my own simple lazy load script:
$(function(){
$('img').each(function(){
var $this = $(this)
$this.data('origImg',$this.attr('src'))
$this.removeAttr('src') // or set a placeholder img
})
var $window = $(window), $container = $('#sliding_content')
window.lazyLoad = function () {
$container.find('img:not([src])').each(function(){
var $this = $(this), left = $this.offset().left
if (!(left < 0) && !(left > $window.width()))
$this.attr('src',$this.data('origImg'))
})
}
})
And then when the divs are animated, call lazyLoad().
Let me know if this works for you. :)
Ok, after some hours I've decided to use JAIL for this. Not the best solution, but better than nothing since I'm dumb with AJAX JAIL aka jQuery Asynchronous Image Loader

Stopping jQuery equal height divs from calculating hidden content

I am using the following jQuery to giv certain divs with the id's #main, #sidebar, #side-event equal height. On most pages, I am using .hide(); to toggle information within the content section of the site. The problem is when JS caluclates the height of the #main div, it's calculating all of the hidden content as well, which I do not want. How can I alter my code so that the height is equal to the tallest div, and not include the hidden information in the equation? In addition I added the code I am using to hide the information upon page load. Here is my page from the site for referencing the issue. Hoping someone can help me with this issue.
http://shadowfaxdigital.com/cdi/events/mba-essentials-business-design-workshops/
Calculating height:
$("#main, #sidebar, #side-event").addClass("heights");
var highestCol = Math.max($('#main').height(),$('#sidebar').height(), $("#side-event").height());
$('.heights').height(highestCol);
Code used to hide the content in the toggles:
//jQuery toggle
$(".toggle_container").hide();
$("h2.trigger").click(function(){
$(this).toggleClass("active").next().slideToggle("slow");
});
you can add the visible selector, this will check if the element has display:none or opacity:0
var $sfd = jQuery.noConflict();
var cols = $sfd('#main:visible, #sidebar:visible, #side-event:visible');
var maxHeight = 0;
$(cols).each(function(){
$(this).addClass('heights');
maxHeight = Math.max($(this).height(), maxHeight);
});
$sfd('.heights').height(maxHeight);
It's not entirely clear what exactly you're asking for help with. .height() will only include the height of child elements that take up space in the layout. So an item that was hidden with .hide() will be marked display:none and will not be included in the height of any parent elements. But an item that has a zero opacity or visibility:hidden will take up space in the layout and will be included in a parent's height.
In jQuery, you can see if anything is visible with:
$("#main").is(":visible");
Or, you can put it directly into a selector to only include visible items:
$("#main:visible")
So, you could change your code to something like this if you only want to include the visible items in your selector:
var visibleItems = $("#main:visible, #sidebar:visible, #side-event:visible");
var highestCol = Math.max.apply(this, visibleItems.map(function() {
return $(this).height();
}).get());
I ran into this issue aswell today. Googled alot and found this thread. Seems this wasn't properly solved, therefore I'm posting my solution:
My issue was that the height-adjusting script was calculating the heights before the elements were successfully hid with jQuery, I therefore copied my height-equalizing script into a $(document).ready(function() {} );
Like this:
$(document).ready(function()
{
if ($('.sidebar').height() < $('#mainwindow').height())
{
var mainwindowHeight = $('#mainwindow').height();
$(".sidebar").css('height', mainwindowHeight+8+'px');
}
});
This solved it for me.
Hope this helps someone.

Categories

Resources