Animate DIV to full height and toggle back to defined height - javascript

I am trying to animate the div to its full height when a button is pressed and come back to its original height if the button is clicked again. The full height of the div is auto as it contains text with different word counts. I tried doing the below codes but it does not work properly.
The CSS :
.category_brief{
text-align:justify;
height:100px;
overflow:hidden;
}
Example 1 : This code does not animate the div when opening to full height , but animates while coming back to old height.
$(".slide").toggle(function(){
$('.category_brief').animate({height:'100%'},200);
},function(){
$('.category_brief').animate({height:100},200);
});
Example 2 : The output of this code is the same as of Example 1
var toggle = true, oldHeight = 0;
$('.slide').click(function(event) {
event.preventDefault();
var $ele = $('.category_brief');
var toHeight = ((toggle = !toggle) ? oldHeight : newHeight);
oldHeight = $ele.height();
var newHeight = $ele.height('auto').height();
$ele.animate({ height: toHeight });
});
Example 3 : This code animates the div to its full height but does not toggle.
var slide = $('.slide');
var slidepanel = $('.category_brief');
// On click, animate it to its full natural height
slide.click(function(event) {
event.preventDefault();
var oldHeight, newHeight;
// Measure before and after
oldHeight = slidepanel.height();
newHeight = slidepanel.height('auto').height();
// Put back the short height (you could grab this first
slidepanel.height(oldHeight);
slidepanel.animate({height: newHeight + "px"});
});
If possible please provide a bit explanation also as i am a newbie..
Update : Solved by the idea from #chazm..
#chazm : thanks for the idea. I got it working by combining 1st and 3rd example ... Here is the code in case anyone needs it .
var slidepanel = $('.category_brief');
$(".slide").toggle(function(){
var oldHeight, newHeight;
// Measure before and after
oldHeight = slidepanel.height();
newHeight = slidepanel.height('auto').height();
// Put back the short height (you could grab this first
slidepanel.height(oldHeight);
slidepanel.animate({height: newHeight + "px"})
},function(){
$('.category_brief').animate({height:100},300);
});

Working with 'auto' height it always quite tricky. I think there are different issues in your examples.
1) Browser can't define correct 100% height. Possible solutions - define height to all its parents. Either set it to 100% (till html tag) or set closest parent as relative (because height is calculated from closest relative parent). If you want to animate div to 100% of the entire page - think of the absolute positioning
2)The same as above i assume
3)When this code supposed to toggle back it can't determine that it should become lower that it is now. Not absolutely sure why though. Probably because 'auto' height from 100% is set to something wrong. You may check in firebug what value it has on the computed tab after that function is toggled back. Probably it will give you a clue
Try to combine 2) and 3). The idea - if toggle is true (it shoud be lowered) then set newHeight = slidepanel.height('100').

The solution depends on your implementation needs. If you know that at first the div should be 100px etc in height and when you click, it maximizes to an unknown height, the following solution would work. If you had a structure similar to
<div class="outer">
<div class="wrapper">Content of unknown length here</div>
</div>
and css
div.wrapper { position:relative; height:100px; overflow:hidden; }
div.outer { position:absolute; height:auto; }
then you'd get a div that is 100px in height, with the content that doesn't fit in 100px cut off. Now when you press the desired button, you could get the height of the wrapper div, since it is a long as it's content is (even though you only see the top 100px) and set the outer div's height according to it. Like so
var newHeight = $('div.wrapper').height();
$('div.outer').animate({height:newHeight},200);
Which would then animate the outer div to display the whole contents. When you click the button again, you could just do
$('div.outer').animate({height:'100px'},200);
And you would again have only the 100px height.

Related

jQuery: How to get the dynamic height of header

I am new to jQuery. And I can't figure out the solution to this problem.
So, the problem is that I want a fixed header on my website. I did that with CSS. But I want to give the main container div(right below the header) a margin-top of the height of the header.
For example, if the #masthead (header) height is 100px, I want to give a margin-top of 100px to .site-container.
I can easily do it with CSS, but due to some reason, there will be different header height on different pages. Or let's suppose that I don't know the height of the header.
So I want to do it using jQuery.
Here is the code -
jQuery(document).ready(function($) {
var header = document.getElementById("masthead");
var header_height = header.offsetHeight + "px";
$( '.site-content' ).css( {
'margin-top': header_height
} );
});
It works perfectly. But there is just one problem.
That, the header height on my website changes in different screen size. In Desktop Screen size, the #masthead height is 80px, in tablet, the screen size is 160px and in mobile, it's 60px.
But, the value of header height does not change with the change in screen size in jQuery.
In jQuery, I want the value of the variable header to change dynamically, with the change in screen size.
Please note that I am working on a WordPress website.
Please help me.
Thank you.
Use:
Use a window resize function
You could also use: (to make your life easier :)
jQuery selectors
.outerHeight() to "Get the current computed outer height (including padding, border, and optionally margin)"
Example code:
jQuery(document).ready(function($) {
// When the window resizes
$(window).on('resize', function () {
// Get the height + padding + border of `#masthead`
var mastHeight = $('#masthead').outerHeight();
// Add the height to `.site-content`
$('.site-content').css('margin-top', mastHeight);
});
// Trigger the function on document load.
$(window).trigger('resize');
});
Write the same function on window.resize.
By the way, after resize the screen reload the page, hope your code will work as it will get the document ready function.
You can execute the same function on both page load and window resize.
jQuery(document).ready(function($) {
function resizeContent(){
var header = document.getElementById("masthead");
var header_height = header.offsetHeight + "px";
$( '.site-content' ).css( {
'margin-top': header_height
});
}
resizeContent();
$(window).resize(resizeContent);
});

Height auto div to expand height

Please check: http://wixwebsite.seobrasov.com for reference.
My goal here is to achieve a body/wrapper div height according to the content instead of having a scrollbar for a 3500px height body on a 500px content.
I have a one page design with divs sliding in and out. There is a wrapper with overflow hidden and position relative that contains all the divs. Inside that, there are the divs having position absolute and height auto. Inside each div there are the content divs with height aut as well and they correctly expand to fit their content. It is all connected to a javascript that does the sliding. The whole thing only works if I set a fixed height to the wrapper div. Otherwise, having height auto on the wrapper or using javascript to set the wrapper div to the inner div height (which is height auto as well) makes the page not to expand & show any content AT ALL.
The first thing you would think about would be that the wrapper div does not expand height due to position absolute of the inner divs. That is only part of the problem. If I do indeed change the position to relative, it will only show part of the divs.
I have tried using javascript to set the wrapper div to take position from inner divs, but those inner divs also have height auto. And I cannot do the javascript on the content divs as there are more using the same class and having different heights, as they expand depending on content.
So the question that follows is:
Even if I achieve the wrapper div to expand height to its containing divs, wouldn't that height be the height of the biggest div? Since they are all on the same page?
Here is some code:
<div class="content-wrap">
<div class="dhome">
content
</div>
<div class="dabout">
content
</div>
etc.
.content-wrap{
overflow:hidden;
position:relative;
clear:both;
height: 3500px -> aiming for auto
}
.dhome,.dabout{
position:absolute;
right:-200%;
height:auto;
}
So far the only solution I'm seeing to this would be to place the content on different pages but I don't think that I'll manage to do the sliding.
Thanks in advance,
So I got this Javascript that does the animation:
function animate() {
var currentPageI = -1;
var pages = [
$('div.dhome'),
$('div.dabout'),
];
var viewsWidth = 1300;
var showPage = function(index){
if(index === currentPageI){return;}
var currentPage = pages[currentPageI];
if(currentPage){
currentPage.stop().animate({left: -viewsWidth})
}
var nextPage = pages[index];
nextPage
.stop()
.css({left: viewsWidth + Math.max(0,(($(window).width() - 980)/2))})
.animate({left: Math.max(0,(($(window).width() - 980)/2))})
currentPageI = index;
};
showPage(-1);
$('a.dhome').click(showPage.bind(null, 0));
$('a.dabout').click(showPage.bind(null, 1));
$(document).ready(function () {
animate();
});
First of all I have added the suggested Javascript at the end of this one and didn't do anything...after that I have added it into the animation script and used nextPage instead of the wrapper childNodes, and it still didn't do the trick. I will further look into this.
Thank you!
set an ID on the div with class="content-wrap"
var wrapper=document.getElementById(IDcontentwrap);
var childNode, childNodes=wrapper.childNodes, i, l=childNodes.length;
var maxWidth=0, maxHeight=0;
for (i=0;i<l;i++)
{
childNode=childNodes[i];
if (childNode.nodeType==1)
{
if (maxWidth<childNode.offsetWidth) maxWidth=childNode.offsetWidth;
if (maxHeight<childNode.offsetHeight) maxHeight=childNode.offsetHeight;
}
}
wrapper.style.width=maxWidth+"px";
wrapper.style.height=maxHeight+"px";

prevent overflow of absolutely positioned dynamic div

I need to get the height and width of a dynamically generated div inside a loop.
Details
I'm dynamically setting the left and top values of a positioned absolute div. This div is in a loop, thus its width, height and position change at an interval n.
(It's basically a div that appears at random places on a page every n seconds.)
The challenge I'm facing is that this div needs to be inside the parent at all times, <body> tag in this case. I have it set to position:relative and even overflow:hidden though it won't help.
Here's a fiddle to make things easier.
Fiddle 1 outside the loop , Fiddle 0 insdie the loop
You will see that because the x and y values are randomly generated the div overflows.
I have found that in order to keep the div in the body it's height and width must be retrieved and calculated with the parent to get the difference in size.
So I can use it the css like
var heightdiff = parentHeight - divHeight;
var widthdiff = parentWidth - divWidth;
in the css via jQuery
top: Math.floor((Math.random()*heightdiff)+0;
left: Math.floor((Math.random()*widthdiff)+0;
Perhaps I'm making a simple mistake but I've tried everything I can think of. To recap all I need to do is to get the height and width of div.
I modified your script :
http://jsfiddle.net/yMT56/1/
Why using document as base ?
var docw = $(document).width();
var doch = $(document).height();
Use body
var docw = $('body').width();
var doch = $('body').height();
Or better, div's parent (requires you to append your div to a container before) :
var docw = $newdiv.parent().width();
var doch = $newdiv.parent().height();
The problem here is that the div has no content and so on no width and height at the moment you calculate it. So I created it at the beginning (notice i added <body> tag in the html part : i don't know how fiddlejs handles this case) :
$newdiv = $('<div/>').css({
'position':'absolute',
'display':'block'
}).html("Hi there, this should appear with in the body.<br/> Just wait it will overflow").appendTo( 'body' );
//parent size, in this case body
var docw = $('body').width();
var doch = $('body').height();
//calculating div size, before it's set, wrong!!
var divh = $newdiv.height();
var divw = $newdiv.width();
I also added a Math.max control to be sure results won't be negatives, especially in case div is larger than his parent.
//positions for x and y
var posx = Math.max((Math.random() * (wdiff) +1).toFixed(), 0);
var posy = Math.max((Math.random() * (hdiff) +1).toFixed(), 0);
And, at the end, only put position for the div :
$newdiv.css({
'left':posx+'px',
'top':posy+'px'
}).fadeIn(2000).fadeOut(2000, function(){
Maybe with that solution, a first div will be displayed before loop starts. A solution would be to use visibility:hidden property, to hide div but always be able to got his width and height.

Set height of div in pixels based off width of browser window in % (jQuery or JS?)

I am trying to set up a black border around a webpage. For the left and right side, just making "width: 5%;" in the CSS is fine. But then I want JS/jQuery to work out how many pixels that is, and make that the height of the top and bottom div.
Is this possible?
Thanks.
This should work for you
var val = $(".leftAndRight").width();
$(".topAndBottom").height(val);
Or with one line:
$(".topAndBottom").height($(".leftAndRight").width());
You can determine the value for the border width programmatically, assign it to all four borders, and also refresh it any time you resize:
var width,
drawBorder = function () {
var body = $('body'),
width = body.width() * 0.05;
body.css('border-width', width + 'px');
};
drawBorder();
$(window).resize(function () {
drawBorder();
});
Demo
If you set the left and right width in your stylesheet and then use JS to give the same border width to the top and bottom, unless you use a resize function your left and right borders will change every time you resize but your top and bottom borders will remain fixed.
You can use .width() to find width without the border and .outerWidth to find the width including the border. I think .outerWidth also gives you the width with the padding you may have to subtract that.

jQuery calculation doesn't add up as expected when toggling height

I have the following function for calculating the height of .node. It then takes away the height of a possible image, .node-image, from the height of the .node, and sets a column, .node-content-column to have a height that is the difference (i.e. 500 - 50 = 450; column becomes 450 in height).
function initColumnSizer() {
imageHeight = $('.node-image').outerHeight(true);
resizeHeight = ($('.node').outerHeight() + 75) - imageHeight;
$('.node-content-column').removeAttr('style');
$('.node-content-column').css('min-height', resizeHeight);
$('.node-content-column').css('height', 'auto !important');
$('.node-content-column').css('height', resizeHeight);
}
This function gets called on page load, and resizes .node-content-column as expected.
It also gets called when a div within .node is toggled using jQuery.toggle(), but this calculation returns a larger number everytime, instead of reverting back to the original once this toggle is reverted.
Can anyone see where I am going wrong with this calculation? Or if I am going about it the wrong way?
Thanks in advance!
Karl
1) Maybe the problem is in outerHeight() function (it takes into account padding and border). Try using just height or clientHeight:
var img = document.getElementById('imageid');
//or however you get a handle to the IMG
var width = img.clientWidth;
var height = img.clientHeight;
2) why do you need to cleanup the whole elements' style?
and then you try to assign height = auto, and after that: height = resizeHeight - what's the purpose for that ? check the logic of your code.
outerHeight(true) will return height + padding + border + margin. Possibly, you might want to use height() ?
Most possible is that "larger number everytime" have always constant difference -- for example 75.
May be you just have some dependecies between .node-content-column and .node?
If your nodes like .node-content-column, .node and .node-image are all singles, then it's better to use IDs for them -- not CSS classes.

Categories