Getting a div's "scrollWidth" when it has an absolute positioned child-div - javascript

I have a problem getting the width of a div's content (of the content, not the div itself).
The usual approach would be Javascript's scrollWidth property, I think.
The problem: within this div, another div is positioned absolute and has a negative right value (-350px). I can't change this (it's a menu, sliding in when you click a button, overlapping other elements. It needs to be positioned like that).
The scrollWidth returns the width of the outer div's content PLUS the negative right-value (in Chrome, didn't test other browsers).
Here's a short example:
/* ... */
http://jsfiddle.net/R4Cs5/12/
But I need the content's width that is accessible by scrollbars.
Any ideas?
Please use Jquery, no plain Javascript.
Thanks in advance.

I see that your jsfiddle doesn't import any jQuery library, while you wanted to use it. Anyway, with jQuery you can use .width to get an element's width see here: jsfiddle.

Related

Weird flicker in jQuery toggle

I have a weird problem and i cant find a solution no matter what i tried.
I have a simple menu that toggles few divs (slide up/down), like this:
<div class="navigation">
<ul class="left">
<li>lorem1</li>
<li>lorem2</li>
<li>lorem3</li>
</ul>
</div>
and a few divs that are being toggled.Pretty simple but there is a lot of code, so i wont paste it here.
Script that makes it work is:
$('.navigation a').click(function() {
var $requested = $(this.getAttribute('href'));
$('.top-drawer').not($requested).slideUp('slow');
$requested.slideToggle('slow')
});
Once the user clicks on the link, the div slides down more than it should, flickers and then it becomes the real height (the height is should be).
Here is a Fiddle. Please be sure to have the "Result" Window at at least 1000+ px wide otherwise it wont work (the error wont be shown).
See my suggestion on this JSFIDDLE
Here an explanation of the changes in there:
The Problem
With all those floating elements inside each .top-drawer jQuery has a lot of issues calculating the height of the div because the elements will move around while sliding up and down.
Suggestion
Switching to inline-block instead. But for that to work with your CSS, particularly with the padding on each .top-drawer, you need to use box-sizing: border-box; on anything that is using padding, inline-block and width with %. If curious you can read about this HERE.
New problem
If you go the route of inline-block (best practice now). You will need to use jQuery 1.8.xx or higher. I noticed in your fiddle you use 1.7.2, which has a bug with border-box that was fixed in versions after that.
Try to understand the code you are using.
This is the way I think jQuery's slideUp(), and slideDown() works; mainly the algorithm changes the height of the element, and display after the height is equal to the height of the element or at "0".
So when you will have your element's position set to relative you will see what you're calling "flickers", specially when you have multiple element at the same position. You will also see these "flickers" when you use fadeIn(), fadeOut() etc, because the display of the element is not instantly set to "none" or anything visible in these cases, but after the animation completes.
Solution:
Set the element's position to absolute. That should solve your issue;
example.

jQuery scrolling doesn't show up

I'm writting a dynamic page using jQuery and I have a problem. I'm for example adding to my html file div's using append() function like this:
$("body").append("<div id ='dd_"+i.toString()+"' class='diamond_div'></div>");
I will be creating different amount of that div's base on datebase so that's why I use this variable i to assign different id's for each div.
My problem is that even if I'm creating that div's in body and when I look at code they are in it, if I check body's height it is 0 (width is ok, something like 1200).
Main problem with that is when there are too many div's they are beyond screen but there is no scroll bar. It's something like div's aren't in body although in code they are in.
Could you propose me any solution for that? Or what am I doing wrong? My line of thought is that I'm using $(document).ready so html file is creating a page, but see empty body so height = 0 and all my div's are beyond body. What do you think about that?
Take care of positioning; position:fixed removes your divs from normal flow ->
Fixed positioned elements are removed from the normal flow. The
document and other elements behave like the fixed positioned element
does not exist.
as W3C says
An empty <div> does not have a height. Thus you could add as many as you want to the page and it will never get any longer. For the scroll-bar to appear you need to either set a height to the <div> with CSS like this:
.diamond_div{
height:100px;
}
Or add some content to the <div> so you would have something like this instead:
$("body").append("<div id ='dd_"+i.toString()+"' class='diamond_div'>hello</div>");
Then your <div> would have height and once there are enough on the page to go beyond the height of the browser, the scroll-bar will then appear.
Following on from your comments. Setting the position to "fixed" removes the element from the workflow and thus will not extend the length of the page in the normal way.

Get content width of an element

offsetWidth isn't good enough for me right now, as this includes padding and border width. I want to find out the content width of the element. Is there a property for that, or do I have to take the offsetWidth and then subtract the padding and border width from the computed style?
Since this comes up first when googling but doesn't have an appropriate answer yet, here's one:
function getContentWidth (element) {
var styles = getComputedStyle(element)
return element.clientWidth
- parseFloat(styles.paddingLeft)
- parseFloat(styles.paddingRight)
}
Basically, we first get the element's width including the padding (clientWidth) and then substract the padding left and right. We need to parseFloat the paddings because they come as px-suffixed strings.
I've created a little playground for this on CodePen, check it out!
It sounds to me like you want to use getComputedStyle on the element. You can see an example of getComputedStyle vs. offsetWidth here: http://jsbin.com/avedut/2/edit
Or:
window.getComputedStyle(document.getElementById('your-element')).width;
I would suggest either scrollWidth or the clientWidth depending on whether you want to account for the scrollbar.
Check out Determining the dimensions of elements or the specification itself.
I have the similar issue where my parent element isn't the window or document... I am loading an image by Javascript and want it to center after loading.
var parent = document.getElementById('yourparentid');
var image = document.getElementById('yourimageid');
image.addEventListener('load'),function() {
parent.scrollBy((image.width-parent.clientWidth)/2,(image.height-parent.clientHeight)/2);
}
Whenever you set the src then it will scroll to the center of the image. This for me is in the context of zooming into a high res version of the image.

How to make an element's height increase with every child added to it

I have a <div> that has children appended to it by a script. These children elements are automatically appended by a PHP script and positioned using position:absolute. I tried to give the parent <div> the style min-height:400px allowing the elements appended to the <div> to increase the parent's height. The only problem is that the height does not increase when I do this. Does anybody know what I can do to fix this?
EDIT: I am not able to use position:relative for positioning my elements. Are there any solutions that allow for position:absolute.
Yes you can use position absolute (yeee♥!)
LIVE DEMO TEST CASE
By simply doing:
$(this).height( this.scrollHeight );
or with pure JS:
this.style.height = this.scrollHeight ;
and adding this to your element's CSS:
overflow:hidden;
overflow-y:auto;
Edit:
The demo tested fine in IE10, Firefox, Chrome, Safari, and Opera.
The key point here is setting the overflow value for the x or y axis (whichever dimensions you need the size of) to auto, rather than the default value of visible. Then the scrollWidth or scrollHeight property can be used on the HTML DOM object to get the full size of the element, including any absolutely-positioned descendants.
Odd as it seems, this is entirely consistent with the fact that setting overflow:hidden for a container clips any absolutely-positioned descendants. Apparently, elements with position:absolute aren't quite as "out of the flow" as we've always been told :)
You should not use position: absolute for this because stuff that is positioned that way will be pulled out of the normal render flow. This results in the parent not noticing that its content s acually very high. Use position: relative for the child div's. This way the parent will grow automatically.

Dealing with scroll bars and jquery .width() method

jQuery's .width() method doesn't seem to account for scroll bars. This is problematic for me, since I'd like to set the width of some children to equal the width of their parent. I used jQuery similar to the following:
$('#contentDiv').width($('#containerDiv').width())
In this example, #contentDiv is the element I'd like to size, and I want to set it to have the width of #containerDiv, which is its parent element. My problem is that this cuts off the side of #contentDiv, as seen in this fiddle.
In my actual code, I have several elements that I'm sizing with jQuery, which all need to fit in the scrollable div, so just setting the css of #contentDiv to 100% is not an option. What's the best way of dealing with scroll bar widths of divs in jQuery?
The best solution I found while working around this solution is this:
http://chris-spittles.co.uk/?p=531
jQuery is all powerful and everything but sometimes a small dash of native JS is all you need to render pixel perfect pages... I hope you will find this solution helpful!
UPDATED:
None of the jQuery width-finding methods account for the scroll bar. In my original example, using .innerWidth(true) LOOKS like it works, but only because it returns and object, which causes width to fail and the inner contents size themselves to fit in the available space, because the example wasn't very good. However, it's possible to write a function to compute the available space in a div with a scroll bar in it, which can then be used to position the contents as you wish.
To write that function, I took advantage of the fact that, when a div is appended to a div with a scroll bar in it, it takes up the full available width (i.e. the inner width of the parent minus the width of the scroll bar).
The function looks like this:
function noScrollWidth(div){
var measureDiv = $('<div id="measureDiv">');
div.append(measureDiv);
var width = measureDiv.outerWidth();
measureDiv.remove();
return width
};
I then use this to size my content div:
$('#contentDiv').width(noScrollWidth($('#containerDiv')));
Working fiddle.
Try this:
$('#contentDiv').width($('#containerDiv')[0].clientWidth)
For more information about that solution, see this StackOverflow answer.
Another approach I'd try is setting both elements' box-sizing property to 'border-box', and see whether setting your contentDiv's width to 100% then works the way you want.
Now that fewer projects worry about crufty old browsers anymore, 'border-box' can make things easier to work with. Be sure to test multiple browsers on multiple platforms, though, because I'm not sure they all handle scrollbars the same way.

Categories