Get updated div size when content size changes - javascript

I have a div that contains several inner divs. In my javascript/jQuery code a function executes, that changes the size of the inner divs using the jQuery css() function. In another function after the first one, I need to read the size of the outer div. Its size should have increased according to the size increase of its contents.
So basically it looks like this:
resizeInnerDivs();
//...do something else...
doSomethingWithOuterDivSize();
When doSomethingWithOuterDivSize is entered, IE8 and IE9 still get the old size for the outer div. IE10, Firefox and Chrome on the other hand return the updated size.
I assume that IE8 and IE9 are not done with recalculating the new size. I tried wrapping doSomethingWithOuterDivSize(); with a setTimeout call. If I wait long enough, I can get a better (but not necessarily correct) size value, depending on the timeout.
Can I somehow force the recalculation of the outer div? How can I get the correct values in IE8 and IE9 as well?

You are probably looking for this:
$('.yourClass').width();
$('someElement').width();
$('#someId').width();
$('any valid jQuery/CSS selector').width();
Resource: http://api.jquery.com/width/
$.width() will give you computed width of your element.

I guess you have either of these two:
The inner divs don't affect your outer div width on IE.
The inner divs are not finished rendering before you are trying to get the
width of outer div, thus you still get the old width.
You can check this by querying width in the console manually:
console.log($('outer_div_selector').width())
If this returns the correct (updated) width, then you are having issue #2. You can solve it like this:
$('outer_div_selector').width(); // this will force rendering to finish before executing the next line
doSomethingWithOuterDivSize();
Otherwise you have an CSS issue (eg. make sure all floats are correctly cleared).

Related

Disable Chrome's scroll preserving feature

I have a page containing a list of items:
Load more button should load some more items via ajax and append it to the items container preserving current scroll position. So after I click it the feed I expect it to look like this (green items are new):
But in fact Chrome 56 executes some computations to make the page stay in the same state, and what I see looks like this:
Is there any way to prevent this smart scrolling position setting in Chrome?
Update: I can reproduce the behavior only if parent container ('body' in my case) has 'display: flex' property (I use it to achieve 'sticky footer' feature).
I solved a similar problem by adding overflow-anchor: none; to the scroll container.
https://wicg.github.io/ScrollAnchoring/
Today it seems that this property was excluded? When adding 'overflow-anchor: none;' as style on a div element I get the message: Validation (CSS 3.0): "overflow-anchor" is not a known css property name.
This is simple. Before performing your AJAX call, save the scroll position of the page to a variable, then, after the call, scroll to the position indicated by that variable. Here is what you should write before your AJAX call:
var scrollpos = window.scrollY;
and here is the code after your AJAX call
window.scrollTo(0,scrollpos)
Hope this works
Why chrome makes calculations to preserve the scroll position? Usually the page will only be longer, so the scroll position stay fixed anyway.
I assume you remove the button, so the position cannot be kept, while content was not reloaded. You should reserve the button space in the dom and remove the reserved space when inserting the reloaded items.

Getting a uniform OFFSET().TOP from transformed element

I'm retrieving text from ajax which feeds a tile whose content changes every 5 seconds. The tile's height is variable so I need to get the offset between the text and another element to set the correct height for the text. (let's say it's like a tile that feeds from Facebook statuses and I have to make sure it doesn't come on top of an absolute-positioned element at the bottom.
Here, the codepen example: http://codepen.io/anon/pen/kFsif (test in webkit, open the console)
What happens is that, as the element is being transformed, sometimes I get a different offset (should always be the same), ranging (in this example) from 62.1875 to even 47.24595642089844. 5 pixels are a lot in my case.
My question is: Is there a way to obtain the offset().top (or it could also be the position().top) of an element that is being transformed so that it gives me always a consistent result?
Thanks in advance.
Edit:
This is an example of how the final markup looks like: http://jsfiddle.net/n3KvJ/
Imagine what I'm trying to do is to set .medium height so that it doesn't touch .bottom. Problem is: .tile height is variable and the position I'm getting changes during a transform.

Element.height() incorrect because browser hasn't finished rendering it?

I am appending div1 into div2 and then getting the height() of div2. If I wait 50ms before calling height() I get a different height. It seems like I am getting the height before the browser finishes rendering div1. Anyone have an idea as to how I can fix this. I am adding quite a few elements and need to check the height after every one, so having a delay between each seems like it could add up to quite the delay.
$(div2).append(div1);
console.log(div2.height()) // 295
where as...
$(div2).append(div1);
window.setTimeout(function(){
console.log(div2.height()) // 245
},50)
There are certain properties you can request that will force a layout. For example, if you request any of these properties:
offsetTop
offsetLeft
offsetWidth
offsetHeight
scrollTop/Left/Width/Height
clientTop/Left/Width/Height
the browser will layout that element before returning the value. If you have a complicated layout, you may need to request properties on more than one object to get proper layout of several items.
See this answer and this article for more details and working demos of the concept.
put your code inside
$( document ).ready(function() {
// your code
});
it will work

JavaScript: Check width of a <div> object before placing it

Consider:
$("#PlotPlace").append('<div style="position:absolute;left:200px;top:40px;font-size:smaller">Hello world!</div>');
I need to execute that line only if the width of the resultant text would be less than 60px. How can I check the width before placing the object?
Unfortunately, the div will only have a width value once it is rendered into the DOM.
I would append that content to an inconspicuous area of the document, perhaps even absolutely positioned so that no flow disruption occurs, and make sure that it is set to "visibility:hidden". That way it will be inserted into the DOM and be rendered, but be invisible to the viewer.
You can then check the width on it, and move it into position and set it to "visibility:visible" at that point. Otherwise, you can remove it from the document.
Maybe you can append it invisible, then check it's width, and then consider to show or hide.
$("#PlotPlace").append('<div style="position:absolute;left:9001px;top:40px;font-size:smaller">Hello world!</div>');
var div = $('#PlotPlace').children("div");
if(div.width() < 60)
div.css({left:200})
Sounds like something you'd have to hack. I don't believe the JavaScript runtime in any browser has an event you can hook into in between calculating the layout and displaying the element, so you can add it in a way that it can't be seen and doesn't affect the height (doesn't cause additional scrolling), and then show/hide it based on the width at this point. It's hacky and ugly, but because you don't have many event hooks it might be the only way to do it.
You can´t. At least not so easy. The text you insert is written in a specific font, which must be rendered by the browser, then you know the width of the element. By the Way, what exactly do you want to insert, with such a restriction? Wouldn´t it be simpler to cut the text within the output parameters?

Javascript clientHeight and alternatives

I am currently trying to modify a Javascript function that "slides in" a <div>. The script as it is requires you to define the height of the div, so it is mostly useless in dynamically filled <div>s. I found some text on the clientHeight property in javascript, but it would appear that it doesn't support <div>s with display set to none (which is the method used to slide the div in). That makes sense, as the height of that div in the client window is nothing.
Basically I was wondering what other methods you all know of, or if there's a way to get around the clientHeight = 0 when display: none.
Thanks!
Oh, and here's the function I'm using:
function getDivHeight(objName) {
return boxHeight = document.getElementById(objName).clientHeight;
}
A simple solution is to set it's visibility to "hidden" and it's display to "block" and measure it. However, some modern browsers will manage to update the page layout during this short time and you will get a nasty flicker. The easiest way to overcome this is to place the element in an absolutely positioned container with overflow set to "hidden".
I've had luck cloning the element, moving it offscreen, then displaying it to get the client height:
var original = document.getElementById(some_id);
var new_item = original.cloneNode(true);
document.body.appendChild(new_item); // item already hidden, so it won't show yet.
// you may wish to validate it is hidden first
new_item.style.position = "absolute";
new_item.style.left = "-1000px";
new_item.style.display = "block";
var height = new_item.clientHeight;
EDIT: Looking through the jQuery code, they do exactly what Tsvetomir Tsonev suggests. jQuery temporarily sets the style to "display: block; position: absolute; visibility: none", and then measures the height, swapping the properties back after the measurement.
So, it looks like you're stuck with having to do something hackish, whether it's cloning the node or risking having it flicker in some browsers... I like Tsvetomir's suggestion better than my initial hack as it, at least, doesn't involve cloning a node into the DOM that you don't need. Either way, the element must not be set to "display: none" in order to measure it's height. Isn't the DOM wonderful? :-)
EDIT 2: Also worth noting that, after jQuery gathers the height, it adds allowances for padding, margin and border sizes, so you may need to as well.
Yes, an element that is not displayed on the page has no dimensions.
It kind of makes sense. Consider an element that has been created and filled with a bunch of text, but not yet added to the document tree. How high is it? Depends on font-size. How big is font-size? Depends where in the document that div is inserted; its parent font-size would inherit through.
Similarly for an element with “display: none”. It's not rendered, so it has no dimensions. Couldn't we ask “how high would this be if it were ‘display: block’”? Turns out no, because if it were displayed, that in itself could change the dimensions of its parent block, and then the dimension of displayed elements would be inconsistent with the dimensions of non-displayed elements!
The typical solution is to unset “display: none”, measure the height of the element, and then immediately re-set “display: none”. The browser won't redraw in the middle of a bit of JavaScript, so you won't see a flicker on the page.
I nkow you guys solved this a long time ago but I thought I should share this since it quite tricky to get the height of a hidden div tag.
heres what I did after reading your post,
I placed the div i want to slide inside a 1px height div with overflow set to hidden.
you dont even need to set the display of the inner div to none since it is already there and if you use offsetHeight it should return the proper height for all browsers and you can use that height to slide your div up an down.
PEACE!!!
In IE you could try scrollHeight, but I'm not sure if it will work or if it is cross browser.

Categories

Resources