prevent overflow of absolutely positioned dynamic div - javascript

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.

Related

el.scrollTop for an element leaves some space at the top of the screen?

I have a simple conversation-body class with overflow: auto property.
I need this div to scroll to top by the amount of its height.
Here is what I have done so far -:
//getting element
var parent = document.getElementsByClassName('conversation-body')[0];
//getting height
var parentHeight = parent.getBoundingClientRect().bottom - parent.getBoundingClientRect().top;
//trying to scroll it up
parent.scrollTop += parentHeight;
This works but it leave some space on the top.
Any suggestion why ?
Here is the link to webpage. You can try above code in the
console.
To confirm, you want to display the next section of the page by the height of the parent?
If so, try using offsetHeight instead of calculating it from the rectangle coordinates.
var parent = document.getElementsByClassName('conversation-body')[0]; //getting element
parent.scrollTop += parent.offsetHeight; // no need to perform height calculation
I think the problem is how you get the parent height. I'm not familiar with getBoundingClientRect, I use offsetHeight. I tried it like that and it worked:
var parent = document.getElementsByClassName('conversation-body')[0]; //getting element
var parentHeight = parent.offsetHeight; //getting height
parent.scrollTop += parentHeight; //trying to scroll it up

Removing extra space in html page

I am currently implementing a tool for a project, and I am having some difficulties to remove some extra space at the bottom of the main container.
Basically, the container that contains the drawings-list and the map, resizes itself on window resize event. The bottom bar is fixed, so it does not affect anything.
$(window).on('resize', function () {
resize();
});
function resize() {
var height = $(window).height();
var width = $(window).width();
var mapHeight = height-260; // 260 for fixed elements
var mapWidth = width-360; // 360 for left hand side list
$('.map-drawings-container ul').height(mapHeight);
$('#map_parent_container > .map').height(mapHeight);
$('.drawings-list').height(mapHeight);
}
When the page is first loaded, it renders properly. Then when shrinking it, we can see a space that seems to be equal to the difference between the original page height and the current one.
Changing the size of the html and body element does NOT fix the issue.
Using the Google Chrome Dev tool, I am not able to select that grey background.
Changing margin-bottom to a negative value on the main container does not remove that space either.
Any clue on how to get this space removed?
Thanks
Sure you don't have an element inside that extends beyond the body with a min-height set on it. This would push the sticky footer down when the body shrinks below that min-height creating the extra space?
Look for all elements with a min-height and try shrinking them.
When the page is first loaded, it renders properly. Then when
shrinking it, we can see a space that seems to be equal to the
difference between the original page height and the current one.
May problem is: resizing the page so try that:
$(window).resize(function(){
var height = $(window).height();
var width = $(window).width();
var mapHeight = height-260; // 260 for fixed elements
var mapWidth = width-360; // 360 for left hand side list
$('.map-drawings-container ul').height(mapHeight);
$('#map_parent_container > .map').height(mapHeight);
$('.drawings-list').height(mapHeight);
});

Div Animate Auto Height

I am working in JavaScript and am unable to use any libraries such as J Query or CSS animations.
I have a Div with an undefined height that auto resizes based on the content that it contains.
The content is changed dynamically through setting the innerHTML value. This works well but the Div size change is jumpy and unappealing. I would like to animate the change in height.
I have seen much code covering this topic but all of the solutions were based on libraries or CSS animations.
Here are my thoughts on how to accomplish the animated dynamic change in height
//get the current height of the div holder
var heightStart = document.getElementById("divHolder").clientHeight;
//the new height, currently I don't know to obtain this
var heightEnd = 1000;
//start a timer to animate the height change
var timer = setInterval( function() {
//clear timer if old height reached new height
if ( heightStart >= heightEnd ){
clearInterval(timer);
}
//set new height
element.style.height= heightStart ;
//incrementing height gradually
heightStart = heightStart + ( heightStart * 0.1 );
} , 50);
So the problem I am having is how to know what the new height would be as it will always be different depending on screen size and the content.
I was thinking I could set the height of the div to a fixed height equal to the heightStart. Then set overflow to none. Then set the new innerHTML content. So the Div wont auto change to fit the new content. I would then use the animate function above to gradually increase the height until the content is fully viewable.
The problem would be is that I don't know how to figure out when the auto height, or when all the content has been displayed height, has been reached.
Thoughts?
Thanks.
First, your heightStart should be assigned before apply new content. and after the new content come in. You can get it's size to heightEnd.
var heightStart = document.getElementById("divHolder").clientHeight;
// APPLY NEW CONTENT HERE
document.getElementById("divHolder").innerHTML = NEW_CONTENT
document.getElementById("divHolder").style.height = 'auto';
var heightEnd = document.getElementById("divHolder").clientHeight;
document.getElementById("divHolder").style.height = heightStart;
document.getElementById("divHolder").style.overflow = 'hidden';

Javascript function to find total page height

I'm after a simple javascript function that will detect the total height of my web page which is dynamic and apply it to the height of a div which is the page background. Would it be possible to implement it?
The div is called bg...
Any ideas? Thanks in advance
Try:
var height = body.offsetHeight ? body.offsetHeight : html.offsetHeight;
document.getElementById ('divID').style.height = height + 'px';
Here an useful documentation:
http://www.quirksmode.org/dom/w3c_cssom.html
Im using currently following code to do that:
var getBodyHeight = function () {
var d = document,
bd = d.body,
dd = d.documentElement,
max = Math.max(
bd.scrollHeight,
bd.offsetHeight,
bd.clientHeight,
dd.offsetHeight,
dd.scrollHeight,
dd.clientHeight
);
return max;
};
This is what I use to figure out the height of content in iFrame for the purpose of adjusting it properly.
var body = document.body,
html = document.documentElement,
height = 0;
height = body.offsetHeight;
if(height === 0){
height = html.offsetHeight;
}
The reason for checking the body first is that the height of html is actually the height of the iFrame, which could be bigger than the content itself. However, in certain cases such as when body has no height, then it falls back to use height of html instead.
For your case, you might want to experiment with a similar scheme. I'm not sure why you have to use a div to set background so I can't really suggest a better alternative (if any).
Solution based on the comment below:
What you can do is the following. Have a div inside the main container with position absolute, width/height 100% and z-index -1. Then it will always be the correct size no matter how large the contain grow or shrink. With this approach, you will have to make sure that container always has size. This is a pure CSS solution, which might be simpler than using Javascript to adjust.
var height = screen.height;
var width = screen.width;
var resolution = width+"x"+height;
alert(resolution);
it gives the resolution of the screen.i know you want page height and width but it will help you later in web development. i am using it as most important part for my web!

Animate DIV to full height and toggle back to defined height

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.

Categories