Animating the height of a continer on jQuery.load() - javascript

I'm using $('#container_div').load(url) to populate a div via ajax. I would like to animate the height to the height of the returned content but really cant figure out how to achieve this.
I've tried using something like this:
$('#main').fadeOut(function() {
$('#main').load(url, function(data) {
var newHeight = $(data).height();
$('#main').animate({height:newHeight}, function() {$('#main').fadeIn();});
});
});
But can see that this is wrong on so many levels. Especially due to the fact that newHeight === undefined.
Can anybody point me in the right direction here? I would be eternally grateful.

Since fadeOut() finishes by hiding the target elements, chances are your #main will be completely hidden by the time your new data is loaded, rendering any animation of height invisible, and therefore pointless.
But you could just use something like $('#main').show(400) which will animate the element from a size of (0,0) and opacity of 0 to whatever size is allowed by the container and contents and a fully-visible opacity of 1 (and run these animations in parallel, making both of them visible).
But assuming you do care more about animating the height than you do about fading, you still have a problem: by the time load() calls its callback, the height of the target element(s) will already be the height of the content (or as close as possible to it). So animating won't do anything.
I posted a plugin on a previous question that will do what you want, but you'll need to use $.get() instead of load():
$.get(url, function(data) {
$('#main').showHtml(data);
});
...where showHtml is defined as:
// Animates the dimensional changes resulting from altering element contents
// Usage examples:
// $("#myElement").showHtml("new HTML contents");
// $("div").showHtml("new HTML contents", 400);
// $(".className").showHtml("new HTML contents", 400,
// function() {/* on completion */});
(function($)
{
$.fn.showHtml = function(html, speed, callback)
{
return this.each(function()
{
// The element to be modified
var el = $(this);
// Preserve the original values of width and height - they'll need
// to be modified during the animation, but can be restored once
// the animation has completed.
var finish = {width: this.style.width, height: this.style.height};
// The original width and height represented as pixel values.
// These will only be the same as `finish` if this element had its
// dimensions specified explicitly and in pixels. Of course, if that
// was done then this entire routine is pointless, as the dimensions
// won't change when the content is changed.
var cur = {width: el.width()+'px', height: el.height()+'px'};
// Modify the element's contents. Element will resize.
el.html(html);
// Capture the final dimensions of the element
// (with initial style settings still in effect)
var next = {width: el.width()+'px', height: el.height()+'px'};
el .css(cur) // restore initial dimensions
.animate(next, speed, function() // animate to final dimensions
{
el.css(finish); // restore initial style settings
if ( $.isFunction(callback) ) callback();
});
});
};
})(jQuery);

It's because $(data) isn't in the DOM, however $(this) is :)
$('#main').fadeOut(function() {
$('#main').load(url, function(data) {
var newHeight = $(this).height();
$(this).animate({height:newHeight}, function() {$(this).fadeIn();});
});
});
However the new height will already be what it's doing to be at this point, and you can't guess the height of the new content because it's all determined by it's container, you may be better off storing and restoring it, something like this:
$('#main').animate({ opacity: 0 }, function() {
var height = $(this).height(); //previous height
$('#main').load(url, function(data) {
var newHeight = $(this).height(); //new height
$(this).height(height) //set old height before animating to new
.animate({height:newHeight})//animate to new height
.fadeIn(); //fade is a queued animation
});
});
I'm animating the opacity here so the display:none doesn't get applies, making this much simpler overall.

First, load your data into a temporary div, which you have hidden way to the left and the top of the page with absolute positioning. You can then get the height of that (as long at it's height in the css is set to 'auto'. Use that height information to animate the div you are showing. Finally, don't forget to remove the temporary div from the dom and set the height of the div you show to 'auto' once the animation is complete.

Related

jquery returning different height everytime I reload

I am trying to create a light box kind of thing in jQuery. For vertically aligning my lightbox,I am using jQuery. Here is my plugin code:
(function($){
$.fn.lightbox = function(){
return this.each(function(){
/*plugin code starts here*/
var self = this;
console.log(self);
/*
* Now we will vertically align the lightbox
* To do that we will calculate the body's height,lightboxes height
* and then subtract later from earlier one.This will give us the total empty space
* So the margin from the top of lightbox will be half of the result we got from subtraction
*/
//calculating body's height
var doc_body_height = $('body').height();
var lightbox_height = $(self).height();
var margin_top = (doc_body_height - lightbox_height)/2;
$(self).css('margin-top',margin_top);
console.log($(self).height());
/*plugin code ends here*/
});
}
})(jQuery);
But the problem is, I am getting either 18 or 300 as height. 300 is the actual height of the div#lightbox,I don't know why the same function is returning different heights randomly.
See Image:
Clearly the div#lightbox is not 18px in height.
You are calculating the height using the $('body').height(). This is the computed value for the height of the body element. That means that for a page with just one visible element that is 50px high on it, the body will return 50px. Conversely, a long page that requires lots of scrolling will return the entire body height, not just the portion that is visible in the viewport.
You need to use $(window).height(); in your calculation instead.
But the problem is, I am getting either 18 or 300 as height. 300 is
the actual height of the div#lightbox,I don't know why the same
function is returning different heights randomly -Rajat Saxena
At original post
var self = this;
console.log(self);
var lightbox_height = $(self).height();
window.innerHeight appear to return viewport of window . See Window.innerHeight .
Try, at console , this page , while periodically adjusting console "height" , and within piece at original post
console.log($(window).height()
, $(self).height()
, $(window)[0].innerHeight
, $(window).height() === $(self).height()
, $(this).height());
If you're only supporting modern browsers then you could use CSS and take advantage of a flexbox http://css-tricks.com/snippets/css/a-guide-to-flexbox/

Images in "display: none" divs not loading onpageload [duplicate]

This question already has answers here:
Get the real width and height of an image with JavaScript? (in Safari/Chrome)
(30 answers)
Closed 9 years ago.
I am scaling images to fit within a div and I want to center them with letterboxes by using positions, but when I try to get the width of the element with .width() immediately after setting the height, .width() returns 0.
For example:
$(image).css("height", "100%");
console.log($(image).width());
This echoes 0 to the console, but if I call $(image).width() from the console sometime later, the correct value is given. How can I get the width of the <img> element immediately after I change it's height?
Edit:
So my code goes something like this:
$(window).load(function(){
cSCMH();
});
function cSCMH()
{
//Some other code
for(var i = 0; i < $("sc mh im img").length; i++)
{
var image = $("sc mh im img")[i];
//More code
$(image).css("height", "100%");
console.log($(image).width());
}
}
The console still receives 0
Edit 2:
Okay so I think I know what the root of the problem is. The images don't appear to load into the page until they are made visible on the screen (I have them in a tab div where the display is set to none onload).
Is there any way to force the images to load even though they are not visible?
I have confirmed this is the issue. The images are not loaded until the div's display is set to block. How can I make the images load in onpageload instead?
Try using the image's load event
function cSCMH() {
$("sc mh im img").load(function () {
var $img = $(this);
$img.css("height", "100%");
console.log($img.width());
}).filter(function () {
return this.complete;
}).trigger('load');
}
Since height() does not provide callback function, You can use animate() here:
$(image).animate({"height": '100%'}, function() {
console.log($(image).width());
})
Also, to make sure all the images are loaded properly, you can wrap your code inside $(window).load(function() { ... });
$(window).load(function() {
$(image).animate({"height": '100%'}, function() {
console.log($(image).width());
})
});
You need to wait for dom change.
$(image).css("height", "100%");
setTimeout(function() {
console.log($(image).width());
}, 0);
setting height in percentage wouldn't set it when you haven't set it's parent's div fixed height. So you can also try by using height 100% to your body like this:
html,body{height: 100%;}

How to show data only when in viewport

I'm planning to use a jQuery plugin called charts.js
for graphs and charts. However, on a larger page, the animations of those graphs get completed even before the user sees them.
My question is, how do we fade in the content of a particular div/section only when it is visible inside the viewport as exactly depicted on charts.js website. The content fades in sequentially as we scroll down and hence even the animations of the graphs aren't missed. How can I achieve this with the help of jQuery?
Take a look at this jsFiddle. The author fades in boxes as they become visible. You porbably need to call chart.js to create the graphs as they become visible, rather than just fade them in (that is if you want the fancy graph animations, rather than just a fade-in :-)) I have tweaked the fiddle and included it below:
$(document).ready(function() {
/* Every time the window is scrolled ... */
$(window).scroll( function(){
/* Check the location of each desired element */
$('.graph').each( function(i){
var bottom_of_object = $(this).position().top + $(this).outerHeight();
var bottom_of_window = $(window).scrollTop() + $(window).height();
/* If the object is completely visible in the window, fade it it */
if( bottom_of_window > bottom_of_object ){
//Code to initialize the graph here.
//This initialization should probably
//be deferred, to ensure performance,
//and the graphs should be marked as
//initialized so we dont't init them
//multiple times (possibly by changing
//their class so .each ignores them).
}
});
});
});
Mika's Viewport Selectors plugin works for the browser window viewport and not html elements. In other words if you got some css like #container{width:350px;height:150px;overflow:auto;} it will not work when scrolling.
I recommend trying his other plugin, Lazy Load
Here's an example: http://jsbin.com/efazos/1/edit
The following code will enable you to determine whether an element is within the window on the scroll of the document. From there you can enable your chart and do whatever animations you like :
<script type="text/javascript">
$(document).ready(function() {
$(document).on('scroll', function() {
//Get Div 1's Top and Left offsets from the Document.
var divTop = $('#div1').offset().top;
var divLeft = $('#div1').offset().left;
//Get the current window height and width.
var winHeight = $(window).height();
var winWidth = $(window).width();
if (divPos <= winHeight && divLeft <= winWidth) {
//Div is visible in window
//Fade in Chart
}
});
});
</script>

jQuery animate on property change

I have I div or some other element which I load content into with:
$('#my_div').load('ajax.php',function(){
//Do random stuff.
}
However the height of the div will then change, causing the page to jump up and down, looking ugly.
Is there a way for it to animate the height when the new content is loaded or changed? I know one can do this with FluidMoveBehavior in C#.
How can I achieve the same effect with Javascript/jQuery?
Here's some Fiddle
When you want to create a height or width animation with jQuery you have to set a number indicating the desired size. I assume that you use height: auto in this case so you have to find a little workarround.
Get the height:
var autoHeight = $("#content").height("auto").height();
Animate to autoHeight:
$("#content").animate({height: autoHeight}, 1000);
And together:
var currentHeight = $("#content").height();
var autoHeight = $("#content").height("auto").height();
$("#content").height(currentHeight);
$("#content").animate({height: autoHeight}, 1000);
Stolen from here
What I do is the opposite. I animate the page to scroll to the top if not already BEFORE I call the load.
So that the top of any new dynamic content is always in view.
I know this isn't the answer you were looking for, but I've found it works best.
You could hide #my_div before the load(), and then slideDown() in the complete function:
$('#my_div').hide().load('ajax.php', function() {
$(this).slideDown();
});
Or, create a temporary element, hide it, append it, use its height to animate #my_div once the load is complete, and then remove it.
$('<span/>').hide().appendTo('body').load('ajax.php', function(text) {
$('#my_div').animate({ height: $(this).height() }, '800').html(text);
$(this).remove();
});

jQuery; Trace the height of an element which is animating via slideDown()

I'm animating an element in jQuery and I need the also animate the margin of another element to follow the height of the animating element while it slides down.
So for example, the slideDown() function starts on element x, and somehow the animate function of the corresponding element knows element x's height as it slides down and copies it, animating in unison.
Hopefully I've explained it well, let me know if you want more clarity.
You may use step property:
$("#first").animate({ /* properties */ }, {
step : function() {
var height = $(this).height();
$("#second").css("margin-top", height);
}
});

Categories