Getting a uniform OFFSET().TOP from transformed element - javascript

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.

Related

How to obtain clientWidth & clientHeight before DIV is visible

I want to obtain the dimensions of a DIV element (used to display a popup menu at the cursor position) while it's style.display='none;', however the dimensions of the DIV always return 0. The only way I seem to be able to get the dimensions is to make the DIV style.display='block;' at 0,0 and then move it to the required position, but that looks jumpy.
I've tried making the DIV visible outside of the visible screen area but that doesn't work. Is there a way to get the clientWidth and clientHeight values whilst the DIV is hidden?
If your DIV is not visible, you won't be able to get its dimensions.
However, there is a workaround. Your div has to be "visible", but that doesn't mean it's opacity and position have to be 1 and relative.
Set the opacity to 0 and the position to "absolute" and you'll be able to get the DIV dimensions.
EDIT
Since I think more people will have a similar problem, I feel I should explain my answer a little more.
If you try to get the size of a hidden element with JavaScript, you will always get 0.
So there are techniques to get the real size without displaying the element to the user. My favourite is the one I already wrote about above. Here are the more detailed steps:
you set the elements opacity to 0. This way it won't be displayed to the end user while you are getting the dimensions.
you set the element position to "absolute". This way it won't take up any space.
now it's safe to set the display to "inline-block".
you read the elements dimensions. This time you'll get the real values.
You set the display back to "hidden" and set the opacity and position back to its original values.
And now you have the size of a hidden element.
If you'd like to know the size of an element onscreen without it being visible you need it to be painted to the screen but not shown.
In order to get clientHeight and clientWidth you need it to be rendered so the calculations can be performed based on the screens current state (unless you have pre-programmed width and height, which I'm guessing you don't)
you can find out more information at MDN here
So you have options:
create your div offscreen using positioning (fixed or absolute) combined with z-index or opacity
use width: 0 and height: 0 and overflow: hidden then use scrollHeight and scrollWidth to find the overflow size
choose which option is best for your site, considering things like responsiveness and screen reflows and repaints

Get updated div size when content size changes

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).

jQuery offset() is returning null for elements below the fold

I suspect I'm misunderstanding something here, but I want to make sure that I'm not crazy. I have some JS that lazy loads some images. Here is a truncated version of what I'm doing:
jQuery(window).scroll(function() {
self.image_holders = jQuery('.image-holder');
jQuery.each(self.image_holders, function(i, placeholder){
if ( jQuery(placeholder).offset() ){
//compare offsets and load image if appropriate
}
});
});
The matched elements that are below the fold or even just partially below the fold are returning null for offset(). What I am trying to accomplish is to load images that are within a certain threshold below the folder before the user scrolls to it. Is this expected behavior for jQuery? How can I get the value of the offsets before they appear above the fold?
Edit: To clarify these elements i need the offset for are NOT hidden or invisible, they are only 'below the fold'.
Right from the Docs:
Note: jQuery does not support getting the offset coordinates of hidden elements or accounting for borders, margins, or padding set on
the body element.
While it is possible to get the coordinates of elements with visibility:hidden set, display:none is excluded from the rendering
tree and thus has a position that is undefined.

Setting CSS position using Javascript

How to set relative 50% 50% position using JS?
I tried:
document.getElementById("id").style.position = "relative 50% 50%";
but it don't seems to work...
You have to set them individually.
I made a variable to point to the style object, because we are modifying more than one property and because with() { ... } is considered harmful.
Also, I set the 50% to both properties because of right to left assignment, and because assignment of this string to the two properties isn't a problem (make sure you understand how this works, e.g. var a = b = [] will set a and b to the same Array object, often not desired).
var elementStyle = document.getElementById("id").style;
elementStyle.position = "relative";
elementStyle.top = elementStyle.left = "50%";
jsFiddle.
I do the following to center an element in its parent - which could be the body or another division.
document.getElementById("elementId").style.marginLeft = "auto";
document.getElementById("elementId").style.marginRight= "auto";
The position property determines how the element is placed in relation to the other elements on the page.
I just did a search to see if the position property can take values like the 50% you show in your question - it can't.
I checked to make sure something new had been added to CSS that allowed setting position to something other than those I show below. I thought that maybe I was wrong about the values that position can take (and do anything -- you can always code any values for various properties, than they are intended to have, but they won't do anything). I see nothing that says position can have values like 50% and actually do something.
The possible values of the position property are:
relative
fixed
absolute
static
inherit
or you can leave it off the element. From what I've seen position: static behaves the same as if you had not coded the position property for the element or class.
Go read about position here
The position property can be confusing until you see the effects of the different values on the position of the element - and even then it is not always clear.
By the way - you can also change style.left and style.top but they will have no effect unless position is set to one of the possible values.
I know that sounds strange but it is how things currently work (and I doubt it will ever be changed) and we have to live with.
So, if you set the top and/or left and nothing happens, look at the position properties value,
You can "play" with property values with the "Inspect Element" facility of your browser. I think all of the major browsers have such a facility. Go read this page about "inspecting"
It allows you to change CSS properties, delete, and add new ones, to the elements as you look at the page in your browser. You can do such things as changing the margin-left to auto and the margin-right to auto and see how the element is positioned. You can change, add, or delete any CSS properties you want.
You can also change the position to one of it several values (static, relative, absolute, or fixed) to see how the element is display in relationship to the other elements on the page.
If you want to remove a property you can highlight its value and press delete and enter - that will remove the property from the element or class, if you are looking at class CSS.
This facility allows you to play "what if" with any element's properties without actually changing the HTML or CSS and reloading the page.
I strongly suggest that you have a pencil and pad of paper and make notes every time you change anything, If you don't you may wind up getting things the way you want them and not be able to remember everything that you changed.
Notes are very important!
To recap - to center an element within its parent, code the what follows - replaced elementid with the id of your element.
document.getElementById("elementId").style.marginLeft = "auto";
document.getElementById("elementId").style.marginRight= "auto";
As for the position value, try them all out with the element inspector in your browser. That is a quick way to begin to understand the effects of the possible values of the position property.

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?

Categories

Resources