jquery animate doesnt work properly - javascript

im trying to animate the width of a table, so the content gets "closed" and "opened". So I manipulate the right and left gap:
$(".gaps").animate({width:"35%"},'slow', function(){
$(".gaps").animate({width: "10%"},'slow');
$("#content").fadeIn();
});
but somehow, its not animating linear. First 10% to 35% works fine, but the width jumps to over 100 at the start of the 10%-animation, so the content is jumping around. I tried some things like "width: "-=25%"", but even that didnt work. Am i having some other problems, dont i just see the obvious?
Thanks!

To finish this i will add the answer from the comments:
Sorry, but tables just do not behave nicely when it comes to animating sizes. Depending on what you are trying to do you might want to wrap your table with to divs: the inner one with static size and the outer one width overflow:hidden and then try to animate the outer one.
<div style="overflow:hidden; background:red;" class="animateMe">
<div style="width:300px;">
<table>...</table>
</div>
</div>
http://jsfiddle.net/mgwo9axL

Related

css z-index changes during opacity animation

I have a very simple page, there are a few stacks of divs and each div has and image inside of it.
Each stack will fadeIn depending on the scroll position, the top stack has an object that overlaps the bottom stack and for some reason during the animation, the z-index changes.
here's the JSBIN, try clicking the fadeIn/fadeOut button and notice how the plate briefly went behind the bottom stack when it's transitioned.
http://jsbin.com/wefediti/1/
please help.
Since your jQuery.each() and therefore the fading animation will be processed synchronously, it is not possible with your approach to make them fade at the very same time.
I suggest you combine those images in the same div and fade them if it is possible for you:
DEMO
function fadePages(num) {
$(".page").animate({
opacity: num
}, 1000*(num+1));
}
do same at same time. It works.
It's a thing of positioning of your divs
I edited. All you need to do is stack your divs right and then re-edit your absolute position. But it works
EDITED CODE
Let me be more specific.
change the order of your divs liek so:
<div class="page1">
<img src="http://i.imgur.com/BleOC.jpg">
</div>
<div class="page">
<div class="bg"></div>
</div>
and that will fix you z-index problem. I made a different call for each div from the JS as well, But that was for testing purposes. I think you're fine with one call
I made the positioning edits as well HERE
But it seems like everyone is modifying it, so hurry up before someone else messes it up lol

Divs too wide when hiding/showing

I have two divs that contain two other divs each. One containing DIV's display is set to none. I have a button that toggles the containing DIVs so I can alternately hide/show the containing div and thus the two divs inside. The inside DIVs are set the 49% width, floated left/right. Problem I have is the fist time the visible DIV is hidden and the hidden one displayed the inside two divs are way too wide. If I resize the width of the browser just a tiny bit with my mouse they are the desired size and any time I toggle the visibility from here on out all is fine. If I reload the page it is wrong on the first toggle. Works the same in IE 10 and Chrome so don't think a browser issue.
The inner two divs both contain high charts that are generated and rendered to the inner divs I want them to be side by side and almost (99%) the width of my page.
Here is snipped of my DIVs to be hidden and shown that contain the inner DIVs with highcharts
<div id="highChartsNG" style="width:99%;display:none;">
<div id="FillRateHigh" style="border:2px solid black;width:49%;float:left;"></div>
<div id="WaitTimeHigh"style="border:2px solid black;width:49%;float:right;"></div>
</div>
<div id="LowChartsPEAK" style="width:99%">
<div id="FillRateLow" style="border:2px solid black;width:49%;float:left;"></div>
<div id="WaitTimeLow"style="border:2px solid black;width:49%;float:right;" ></div>
</div>
This is a snippet of the javascript function I call on a button click to toggle on/off on the display of two containing DIVs
document.getElementById("highChartsNG").style.display = "none";
document.getElementById("LowChartsPEAK").style.display = "block";
Fiddle showing problem, see comment of mine below on how to reproduce http://jsfiddle.net/rplace/UTTz4/1/
Okay, after hours of searching I finally found the problem (I think). I was determined to find the solution =).
The problem is multiple-fold.
The first problem was the display:none; property on the second chartcontainer. For some reason the widths calculated for the charts and their containers were incorrect for the hidden div. So I removed the property from the HTML, and instead hid it dynamically with document.getElementById("LowChartsPEAK").style.display = "none"; in the JS right after the chart rendering functions. If you do this, your SVG's will fit your containers already, although the last one has a slight shift.
Apparently HighChart doesn't like percentage-based parent containers. When you go to your updated fiddle , run the fiddle with both:
<div id="wrapper" style="width: 800px;">
<div id="wrapper" style="width: 100%;">
Open the console and check the results (container name - SVG width - container width). When the wrapper is given a pixel width, all container widths are equal (as it should be). Now check the wrapper with percentage width: your last SVG will be about 6 to 20 pixels smaller. The only solution I have found for eliminating that small shift in the last container, is that somewhere a top container must have a pixel-width.
EDIT: pt's and em's also work. It's only % that causes problems
If you are hiding DIV, you should be aware that browser won't calculate %-based widths with display:none. Then if browser won;t calculate DIV, then also Highcharts are not able to do it ;)
Check this FAQ - when showing chart update his size or call reflow().

Hide child <div>s as parent div shrinks?

I am trying to write a zoom in/out feature on a web app I am making using the jqueryUI slider.
I am having difficulty handling when my parent div shrinks too much, and cramps its child containers.
<div class="puck originator inline-block" style="width: 310.5px; left: 0px;">
<div class="conflicted inline-block originator">
<div class="right-number">I should stay</div>
<div class="left-number">I should stay</div>
<div class="middle-number">I Should disapper</div>
</div>
</div>
Here is the relevant section of code I have
http://jsfiddle.net/aQKwE/
Basically I have the parent div (class 'puck') that is being shrunk using a jquery slider. For this code I just used a text box, but same idea.
When I shrink that div, the containing divs stick around and are very garbled.
I want to be able to remove the middle child div when it becomes to cramped, leaving the left and right child divs to occupy all the space
Furthermore, if it becomes to cramped yet after that, I want to remove the right div, leaving only the left.
Finally I want to be able to remove all contents so that nothing more than the background of the parent shows.
Is there a way to do this easily, preferably through CSS? I don't want to write more javascript code to set 'display:none' on each child div, since it seems like some CSS rules should handle this.
Any ideas?
There's not really any logic built into CSS to handle something like this. You can set rules based on viewport size, but that won't help in this case.
I updated your jsfiddle with this code so you can test it and see what you think, but essentially I just added some checks in your javascript function to hide based on the width submitted.
var newwidth = $('#text').val();
$(".middle-number").show();
$(".right-number").show();
if (newwidth < 280) {
$(".middle-number").hide();
}
if (newwidth < 180) {
$(".right-number").hide();
}
$('.puck').css('width',newwidth);

Problem with animate jquery div with different pace

While I was animating two boxes with jQuery at same pace with setting marginTop, the second box will move faster than the first box.
<div id="box1" style="width:500px;height:80px;background-color:blue;">box 1</div>
<div id="box2" style="width:500px;height:80px;background-color:green;margin-left:510px;">box 2</div>
<script type="text/javascript">
jQuery("#box1").animate({marginTop:"-=80px"}, {duration: 1500});
jQuery("#box2").animate({marginTop:"-=80px"}, {duration: 1500});
</script>
However, when I apply the same setting Top, both box move at same pace.
<div id="box1" style="width:500px;height:80px;background-color:blue;position:relative;">box 1</div>
<div id="box2" style="width:500px;height:80px;background-color:green;margin-left:510px;position:relative;">box 2</div>
<script type="text/javascript">
jQuery("#box1").animate({top:"-=80px"}, {duration: 1500});
jQuery("#box2").animate({top:"-=80px"}, {duration: 1500});
</script>
Any idea why this happening this way?
You can see the effect more clearly in this fiddle
The reason why it is happening is because your second div is below the first div. And the margin property is relative to the elements surrounding it. The top div will move slower because the element that is above (in this case the body) is not moving. But your div on the bottom has to move faster in order to maintain that margin property relative to the element above it. In other words, it wants to MAINTAIN that property once the animation is finished.
In my fiddle, each div starts with margin-top: 100px. Now when they are animated, they want to marginTop: "-=80px", which means that they need to end up at margin-top: 20px. In the top elements case, it only needs to move 80px upward, because body isn't moving. But the bottom div needs to move 80px PLUS the amount that the top div moved, which is another 80px, for a total of 160px. The div needs to move 2x the amount of pixels in the same amount of time, so it will move faster.
We can further illustrate that the margin property is a relative property from this fiddle. Even though I'm only animating the top div, the bottom div is moving too because it needs to keep that margin value consistent.
The reason why your second piece of code allows the divs to move at the same speed is because the top property is not a relative property of any element besides it's container (the right container that is, probable that it's not it's direct container), so they will both move at the same speed.
Not sure if this is clear.
If you inspect the green box with Firebug or Chrome, you'll see that it's left margin has pushed itself underneath the blue box. It's still technically in line with the blue box, so jQuery calculates the end position (in line with the blue box). They end up next to each other at the same time just like your second example, but it just looks different. In the second example they look inline, so appear to move inline. This is what I have observed, anyway.

jQuery slide is jumpy

I tried to slide in and out a DIV with the toggle function of jQuery but the result is always jumpy at the start and/or end of the animation. Here's the js code that I use:
$(document).ready(function(){
$('#link1').click(
function() {
$('#note_1').parent().slideToggle(5000);
}
);
And the HTML:
<div class="notice">
<p>Here's some text. And more text. <span id="link1">Test1</span></p>
<div class="wrapper">
<div id="note_1">
<p>Some content</p>
<p>More blalba</p>
</div>
</div>
</div>
You can also see the complete example here: jQuery Slide test
I usually use Mootools and I can do this slide without any problems with it. But I'm starting a new project in Django and most app in Django use jQuery. So for that and after reading this jQuery vs Mootools I decided that will be a good occasion to start using jQuery. So my first need was to slide this DIV. And it didn't work properly.
I did more search and I found that's an old bug in jQuery with margin and padding applied to the DIV. The solution is to wrap the DIV in another DIV. It didn't fix the thing in my case.
Searching further I found this post Slidedown animation jumprevisited. It fix a jump at one end but not at the other (Test2 in jQuery Slide test).
On Stack Overflow I found this jQuery IE jerky slide animation. In the comments I saw that the problem is with the P tag inside the DIV. If I replace the P tags with DIV tags that fix the problem but that's not a proper solution.
Lastly I found this Weird jQuery behavior slide. Reading it I understood that the problem resolved by switching from P tag to DIV was with the margins of the P (not present in the DIV) and the collapsing of margins between elements. So if I switch the margins to paddings it fix the problem. But I loose the collapsing behavior of margins, collapsing that I want.
Honestly I can say that my first experience with jQuery is not really good. If I want to use one of the simplest effect in jQuery I have to not use the proper function (slideToggle) but instead use some hand made code AND wrap the DIV in another DIV AND switch margins to paddings, messing my layout.
Did I miss a simpler solution ?
As krdluzni suggest, I tried to write as custom script with the animate method. Here's my code:
var $div = $('#note_2').parent();
var height = $div.height();
$('#link2').click(
function () {
if ( $div.height() > 0 ) {
$div.animate({ height: 0 }, { duration: 5000 }).css('overflow', 'hidden');
} else {
$div.animate({ height : height }, { duration: 5000 });
}
return false;
});
But that doesn't work either because jQuery always set the overflow to visible at the end of the animation. So the DIV is reapearing at the end of the animation but overlaid on the rest of the content.
I tried also with UI.Slide (and Scale and Size). It works but the content below the DIV doesn't move with the animation. It only jump at the end/start of the animation to fill the gap. I don't want that.
UPDATE:
One part of the solution is to set the height of the container DIV dynamically before anything. This solve one jumping. But not the one cause by collapsing margin. Here's the code:
var parent_div = $("#note_1").parent();
parent_div.css("height", parent_div.height()+"px");
parent_div.hide();
SECOND UPDATE:
You can see the bug on the jQuery own site at this page (Example B):
Tutorials:Live Examples of jQuery
THIRD UPDATE:
Tried with jQuery 1.4, no more chance :-(
I found what works consistently is setting an invisible 1px border:
border: 1px solid transparent;
No need to fix the width or height or anything else and the animation doesn't jump. Hooray!
The solution is that sliding div must have the width set in pixels. Do not use 'auto' nor '%'. And you will have great result! The problem is in inline elements thats are in a sliding div.
but if they have width in px the height will be identical. Try it.
I've ran into this problem today. I did notice however that disabling all CSS fixed the problem. Also I knew it worked fine before so it must have been recent changes that caused the issue.
It turned out I used transitions in CSS to ease in and out of hovers.
Once these transitions were removed from the elements I was adding everything was fine.
So if you have the same issue, just add these lines to the elements you're adding:
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
-ms-transition: none;
transition: none;
(I might have abused transitions a bit by not just adding them to the elements I want to have transitions for, but using them for the entire website.)
Try removing all CSS margins from all the elements. Usually jerky animation comes from margins not being taken into account by the animation framework.
Jerking happens when the parent div ".wrapper" in your case has padding.
Padding goes on the child div, not the parent. jQuery is animating height not padding.
Example:
<div class="notice">
<p>Here's some text. And more text. <span id="link1">Test1</span></p>
<div class="wrapper" style="padding: 0">
<div id="note_1" style="padding: 20px">
<p>Some content</p>
<p>More blalba</p>
</div>
</div>
</div>
Hope this helps.
I find animate() is the most reliable way to animate anything in jQuery (cross browser at least).
This dynamically wraps the content in a div, then animates the height of that div wrapper by using the height of its inner content.
http://jsfiddle.net/BmWjy/13/
$('a').click(function(event) {
event.preventDefault();
xToggleHeight($(this).next());
});
//For each collapsible element.
$('.collapsible').each(function() {
//Wrap a div around and set to hidden.
$(this).wrap('<div style="height:0;overflow:hidden;visibility:hidden;"/>');
});
function xToggleHeight(el){
//Get the height of the content including any margins.
var contentHeight = el.children('.collapsible').outerHeight(true);
//If the element is currently expanded.
if(el.hasClass("expanded")){
//Collapse
el.removeClass("expanded")
.stop().animate({height:0},5000,
function(){
//on collapse complete
//Set to hidden so content is invisible.
$(this).css({'overflow':'hidden', 'visibility':'hidden'});
}
);
}else{
//Expand
el.addClass("expanded").css({'overflow':'', 'visibility':'visible'})
.stop().animate({height: contentHeight},5000,
function(){
//on expanded complete
//Set height to auto incase browser/content is resized afterwards.
$(this).css('height','');
}
);
}
}
You could write a custom animation using the animate method. This will give you absolute control over all details.
I noticed if you have a <br /> after your container <div> the animation will also be jumpy. Removing this resolved my problem.
css padding and jquery slideToggle doesn't work well together. Try to box out padding.
There are obviously a lot of different solutions to this issue - and depending on your layout, different solutions have different results.
Here was what I had (stripped down)
<div>
<p>Text</p>
</div>
<div class="hidden">
<p></p>
</div>
When I would use jQuery to show <div class="hidden">, the margin on the <p> element would collapse with the margin of the <p> element above it.
I thought it was strange since they were in different <divs>.
My solution was to eliminate the margin on the bottom of the <p>. Having a margin on one side prevents the margin from the bottom of the first <p> from collapsing with the top of the second <p>.
This workaround solved my problem, can probably be applied to others, but may not work for all.
You just have to modify the up, down effects in effects.js to have them take into account margins or paddings that may exist and then adjust what they perceive to be the total size of the element to accommodate those values...something along these lines....
Effect.BlindDown = function(element) {
element = $(element);
var elementDimensions = element.getDimensions();
//below*
var paddingtop = parseInt(element.getStyle('padding-top'));
var paddingbottom = parseInt(element.getStyle('padding-bottom'));
var totalPadding = paddingtop + paddingbottom;
if(totalPadding > 0)
{
elementDimensions.height = (elementDimensions.height - totalPadding);
}
//above*
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false,
scaleX: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
effect.element.makeClipping().setStyle({height: '0px'}).show();
},
afterFinishInternal: function(effect) {
effect.element.undoClipping();
}
}, arguments[1] || { }));
};
Try setting the 'position' property of the the container (in this case the .notice div) to 'relative'.
Worked for me.
Source: slideToggle height is "jumping"
There are a lot of suggestions here and a lot of back and forth as to what works. For me, the behavior problem was when the animation of expanding the container would over expand and then bounce back to the correct expansion height (all done as part of the one animation). In way of example, the animation would expand to a height of 500px initially and then retract to 450px. There was no problem with collapse.
The solution that worked was to add to the expanding/collapsing div, a CSS of:
white-space: nowrap;
That worked perfectly - smooth expansion to the correct height.
I had the same issue, but not a single one of the proposed solutions worked for me, so I propose a solution that eliminates relying on slideToggle() altogether.
Spark Notes: Load the page as normal, collect the height of each element you want to toggle, store that height in a special data attribute, and then collapse each element. Then it's as easy as changing the max-height between the value in the element's data-height attribute(expanded) and zero(collapsed). If you want to add extra padding and margins, etc to the elements, I recommend storing those in a separate CSS class to add and remove with the max-height property.
Place the jQuery right after the elements you want to toggle and allow them to execute during page load (so you don't have to watch them all load and then collapse).
HTML
<ul id="foo">
<li>
<h2>Click Me 1</h2>
<div class="bar">Content To Toggle Here 1</div>
</li>
<li>
<h2>Click Me 2</h2>
<div class="bar">Content To Toggle Here 2</div>
</li>
</ul>
CSS
#foo>li>div.bar {transition: all 0.5s;
overflow: hidden;}
jQuery
$('#foo h2').each(function(){
var bar = $(this).siblings('.bar');
bar.attr('data-height', bar.height()); //figure out the height first
bar.css('max-height', '0px'); //then close vertically
});
$('#foo h2').click(function(){
var bar = $(this).siblings('.bar');
if ( bar .css('max-height') == '0px' ){ //if closed (then open)
bar.css('max-height', bar.data('height') + 'px');
} else { //must be open (so close)
bar.css('max-height', '0px');
}
});
Here is a working JSFiddle: http://jsfiddle.net/baacke/9WtvU/
The problem is that you are performing the action on the parent, doing this removes the CSS related to that element.
You need to run the slide on your note1, not the parent of note 1.
I had the same issue and fixed it by moving down a level.
For me removing the min-height from my container solved the problem.
You might try adding a doctype if you don't have one, it worked for me on IE8 after I found the suggestion here on SO: jQuery slideToggle jumps around. He suggests a strict DTD but I just used the doctype that google.com uses: <!doctype html> and it fixed my problem.
i came across the same bug took days to find a solution. the problem is when the element is hidden jquery is getting the wrong height. top fix it you must get the hight before hiding and use a custom animation to that height. its tricky go here for a better explanation
I had the same problem with 'jerkyness' with divs inside my nav tag - my aim is to show an unordered list on hover of the div (if one exists). My lists are dynamically created so they do not have a fixed value.
Heres the fix:
$("nav div").hover(
function() { // i.e. onmouseover function
/****simple lines to fix a % based height to a px based height****/
var h = jQuery(this).find("ul").height(); //find the height
jQuery(this).find("ul").css("height", h);
//set the css height value to this fixed value
/*****************************************************************/
jQuery(this).find("ul").slideDown("500");
},
function(){ // i.e. onmouseout function
jQuery(this).find("ul").slideUp("500");
});
});
Ran into this issue today, saw this question, and started tinkering based on what I saw here. I solved our jumpy issue by removing the position:relative from the CSS of the containing div. No more weirdness after that. My 2 cents.
Make sure you don't have CSS transition rules set globally or on your container or any included elements. It will also cause jerkiness.
In my case I solved it adding style="white-space:nowrap;" to the element to prevent miscalculations on the jQuery function; no need to set a fixed width unless you need to wrap.
I was using slideDown() like this
$('#content').hide().delay(500).slideDown(500);
For me, it was the main container #content element. I was having it hidden and then calling slideDown(). I removed the padding property in the CSS and everything worked fine after that. It's usually a margin, padding, or % width, so the easiest method is commenting out each property and testing them 1 by 1 to get your results.
I just learned that this problem can also occur if there are floated elements in the expanding/collapsing element. In that case, a clearfix (clear: both;) at the end (still within) the animated element can get rid of it.
I had the same issue. I fixed it by adding this:
.delay(100)
Guess giving it more time to think helps it along?
Adding my solution: turned out my issue was flexbox (only in chrome). I had align-items: baseline; set on the parent element. Set align-self: center; to my slideToggling full-width child element and it cleared it right up. Great use of two hours.
For me the solution was, that i had a CSS style definition like following:
* {
transition: all .3s;
}
Removing this was the solution!

Categories