I'm trying to copy a element's dimensions and the position(relative to the document) onto another element.
Ex:
var SelectedElement = $("div#MyTargetElement");
// The CopiedButEmpty element is a div with absolute position that is meant to hover/float above the selected element.
$("div#CopiedButEmpty").css("width", SelectedElement.width()).css("height", SelectedElement.height())
.css("left", SelectedElement.offset().left).css("top", SelectedElement.offset().top)
.css("marginTop", SelectedElement.css("marginTop")).css("marginLeft", SelectedElement.css("marginLeft"))
.css("marginRight", SelectedElement.css("marginRight")).css("marginBottom", SelectedElement.css("marginBottom"))
.css("paddingLeft", SelectedElement.css("paddingLeft")).css("paddingTop", SelectedElement.css("paddingTop"))
.css("paddingRight", SelectedElement.css("paddingRight")).css("paddingBottom", SelectedElement.css("paddingBottom"));
But in some cases, it still does not give me the correct position. Am I missing something? Is there any way to easily copy an elements position(relative to the document), so my element "CopiedButEmpty" can hover the element.
I wonder why you didn't chose to use jquery clone().
Related
I'm creating an absolutely positioned element with Javascript. This element will be used in various different contexts. So the element in relation to which it is positioned could be its parent, or any other element including the body.
I need to set the element's position (e.g. left and top) before I place it in the DOM. Is there some way to find out which element my new element will be positioned relative to? I know which element will be its direct parent. But the closest element that has a position style that is not static — the element my new element will be positioned in — might be a different element.
I considered traveling up the DOM tree and checking each parent element's position style, but that seems like a really convoluted way to do it.
So, is there a better way to find out which element is the reference frame for my absolutely positioned element's position?
Sounds like you want .offsetParent(), which will grab the first positioned parent of the element (I assume in the most efficient way possible). As per the definition of absolute positioning,
absolute
Do not leave space for the element. Instead, position it at a
specified position relative to its closest positioned ancestor if any,
or otherwise relative to the containing block. Absolutely positioned
boxes can have margins, and they do not collapse with any other
margins.
It does exactly what you're looking for.
EDIT: For a pure JavaScript solution, iterating over every parent is the only way to go. Try:
function offsetParent(elem) {
var parent = elem.parentNode;
if (window.getComputedStyle(parent).position !== 'static' || parent.tagName === 'BODY') {
return parent;
} else {
return offsetParent(parent);
}
}
There are methods, but they will require iteration through all the DOM elements, which might not be quick.
Here are possible selection of elements for you in jQuery:
$('*').filter(function(){
var position = $(this).css('position');
return position === 'absolute';
});
If you have target selector, and need to figure out if it's nested to any of parent elements, with absolute positioning, you may traverse up among all the parents with parent():
// it will return all the parent selectors, with the absolute positioning
$(targetSelector).parents().filter(function() {
var position = $(this).css('position');
return position === 'absolute';
});
See also .offsetParent(), which might be useful at some degree, but not for your purposes, as you have a bit different task. And here's why:
.offsetParent() method allows us to search through the ancestors of these elements in the DOM tree and construct a new jQuery object wrapped around the closest positioned ancestor. An element is said to be positioned if it has a CSS position attribute of relative, absolute, or fixed.
That means, it will grab the first parent element, which has any of those CSS position attributes defined: relative, absolute, or fixed. As soon as you are in need to filter out only "position:absolute;" it's not working the way you expect, and you need to take the solution I proposed several paragraphs above.
I have a slider that contains N elements. Each element will by translated by N pixels when the user click on the next button. When the element is out of the wrapper div, it disappears because it is overflowed by another element.
My plugin does not use any margins, just the transform property.
I would like to know if there is a way to know if my element is out of the div. :visible does not work for my problem because the element is already visible but overflowed.
If I understand correctly, one way to do it would be to compare the position of this element to the size (width/height or both) of his parent.
With Jquery you could do it this way:
<script>
//This is the position of the right side of the element
//relative to his parent
var rightPos = $("#element").position().left + $("#element").width();
//And bottom side
var botPos = $("#element").position().top + $("#element").height();
if (rightPos > $("#element").parent().width()) {
//The element is outside the right limit of the the parent block
} else if (botPos > $("#element").parent.height()) {
//It's outside the bottom limit of the parent block
}
</script>
If it's not the parent you could then adapt this code to compare the position to the width of the correct div, preferably by using the jquery offset() method instead of position().
By determine parent width and get child width then use if condition
if($('span').width() > divWidth){
alert('Overflowed!');
// do something!
}
jsFiddle Demo
if you update your question with your html then I can update with your codes.
You could give the wrapper div the CSS property of overflow: hidden
This would mean that any elements inside of it are not visible when they leave the bounds of the wrapper.
Otherwise you could check whether your element is outside of the wrapper div using jQuery to compare the position to that of the parent.
There is a nice tool for testing if an element is visible on the screen.
Detect if a DOM Element is Truly Visible
It looks at an object and checks each of its parents to see if it’s still visible to the user.
I need to change the horizontal position of an element. To do this I change its left attribute with .css('left', value). That would move the element relative to where it should be if there was no left value defined.
Now I need to recalculate the position to move the element somewhere else, to do that I need the position where the element should be if I had not changed its left attribute.
I could remove the left value and ask for its position but then the element would also move and would like to avoid that since I may make the element jump between positions.
How could I get the position where the element would be?
The element doesn't jump between position if you change the left style multiple times. As long as your function is running, there are no updates in the browser. You can safely reset the left style, get the positon, and then set a new left value.
One way would be to read the default left value of the element on DOM-ready and add it to the element as a data-* attribute on the element - let's call it data-default-left or something similar. You could then always refer to that value when you need the default value further on.
The data-* are easy to work with using jQuery's .data() method.
Setting left to 0, recalculating, and setting left to the new position would be the easiest change in your case. In my experience the browser will not repaint between css updates.
Some other options:
Use absolute positioning instead of relative. Then you're origin is consistent.
Use the jQuery UI position plugin. It lets you set the position of an element relative to another. Very useful.
how about use .data() to store this info before starting moving it? Then u just gather it back there everytime u need.
Simple. Store the initial left amount in a variable on dom load and then reference it later when you do your other calculations:
$(function () {
var $element = $("#ME_ELEMENT_ID");
var initialLeft = $element.offset().left;
// Change your left here
$element.css('left', '200px');
// initialLeft still contains the old value
});
How do know width of an inline element, without adding to document?
With adding
var span = document.createElement('span');
span.innerHTML = 'Hello, world!';
span.offsetWidth; //0
document.body.appendChild(span);
span.offsetWidth; //70
How without adding to document?
Sorry for my english)
The width of an element does obviously depend on the styles used (e.g. on the font size), so it is impossible to compute the width of the element without knowing where it is in the DOM.
You may add it to some invisible element if you don't want it to show on the screen.
You cannot get a width of an element if the element itself is not part of the DOM.
You need to append it, but you may also position it outside the visible area (with position: absolute and a negative left/top property) and remove it once you got the width
Until the element is added, there's no way to know for sure how wide it is, because it depends on the styling context.
jQuery's width() method has a trick that it uses for display: none elements, I don't know if it will work for an element that hasn't even been added to the DOM (it works by temporarily showing the element, getting the width, then hiding it again).
I would like to calculate the vertical position of a <div> with jQuery.
How would I do this?
Here's an illustration describing what I mean:
I think you're looking for its offset from the top of the page, right?
$('#div').scrollTop();
If that's not it, maybe the offset would work:
$('#div').offset().top;
Okay, now that it needs to be relative to the parent, try this:
$('#div').position().top;
$('#innerDiv').position()
Get the current coordinates of the
first element in the set of matched
elements, relative to the offset
parent.
jQuery Manual for position()
I think you're looking for
$(elem).offset();
http://api.jquery.com/offset/
If you want it relative to it's container, then you're after http://api.jquery.com/position/ instead.
jQuery has several functions to help you find the offset that you are looking for.
var element = $("#your_element");
// Get the current coordinates of the first element in the set of matched elements, relative to the document.
element.offset()
// Get the closest ancestor element that is positioned.
element.offsetParent()
// Get the current coordinates of the first element in the set of matched elements, relative to the offset parent.
element.position()
// Get the current horizontal position of the scroll bar for the first element in the set of matched elements.
element.scrollLeft()
// Get the current vertical position of the scroll bar for the first element in the set of matched elements.
element.scrollTop()
For more information read about these at the jQuery offset api page.
I reckon that the jQuery API "position()" isn't what you are looking for, since it is defined as "the current position of an element relative to the offset parent" (basically it corresponds to element.offsetTop)
Therefore if you want the top position of the element relative to its parent (not necessary the offset parent), use this instead:
var top = (element.parentNode == element.offsetParent) ? element.offsetTop : element.offsetTop - element.parentNode.offsetTop;