Using element.offset().left gets you the element's offset position from its parent. Is there any way to get the offset position from another element? For example, here's my html:
<div id="tile_id_579" class="product_tile">
<div class="selectContainer">
<table style="width:100%;">
<tbody>
<tr>
<td>
<div id="select-undefined" class="tzSelect">
<div id="options-undefined" class="tzOptions" style="max-height: 500px; width: 250px; display: none; min-width: 118px;">
<ul class="dropDown" id="dropdown-undefined">
<li><div class="header">Hand-Tossed Style Pizza</div>
<div class="subheader">The crowd-pleasing pizza that everyone can agree on.</div>
<div class="optkey">0</div>
</li>
<li><div class="header">Pan Pizza</div>
<div class="subheader">Our Pan Pizza is America's favorite!</div>
<div class="optkey">1</div>
</li>
</ul>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
It's generated from a database. Using offset().left gets me the offset from the #selecct-undefined div, but I need to get how far the #options-undefined div is from the .selectContainer div. Is this possible?
EDIT TO ADD
Tried both of these, and both return the same thing: top: 381, left: 0. But left is NOT 0 in relation to the document; it can't be.
var tip = $('#tile_id_579 #options-undefined .header');
tip.first().position();
and
var tip = $('#tile_id_579 #options-undefined .header');
tip.first().offset();
How is it possible that left is 0 for both when this is where the div is? Doesn't 0 left imply that it's all the way at the left of the browser window?
Since your element is indeed within that parent you specified you can use .position() instead of .offset(). But if .selectContainer is not the closest relative parent you will need to get the position of both your element and that "other" element and calculate the difference.
var myPos = $('#options-undefined').offset();
var otherPos = $('#options-undefined').closest('.selectContainer').offset();//if #options-undefined wasn't a child of .selectContainer you would do $('.selectContainer').offset();
var _offset = {
top: otherPos.top - myPos.top,
left: otherPos.left - myPos.left
}
Related
I'm trying to position an element exactly in the same "X" coordinate of another element.
There are many solutions in stackoverflow to get the position using something like this:
var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);
My problem is that when I try to apply the value on "element.style.left" of elements that are inside other elements positioned as "absolute", the element position becomes larger because the "left: 0" is the beginning of the absolute element and not "left: 0" of the document.
The more "nested" elements exist using "absolute", the greater the difference.
Is there any way to detect elements using "position: absolute" so that I can offset the actual value to be positioned by discounting the "left" of each element with "absolute"?
This is the problem:
<span class="dropdown-label">Some menu</span>
<nav class="dropdown-menu">
<a class="item">Email</a>
<a class="item">Twitter</a>
<a class="item">Tumblr Blog</a>
<span class="dropdown-label">Another menu</span>
<nav class="dropdown-menu">
<a class="item">Foo</a>
<a class="item">Bar</a>
<a class="item">I'm Batman</a>
<span class="dropdown-label">Yet another menu</span>
<nav id="finales" class="power-dropdown">
<a class="item">Foo</a>
<a class="item">Bar</a>
<a class="item">I'm Robin</a>
</nav>
</nav>
</nav>
Each dropdown needs to be positioned with the "lef" of its respective label, but we have dropdowns inside other dropdowns and each dropdown is positioned absolutely.
I know I can avoid the problem by using a "container" for each dropdown positioned as "relative" and so I do not need to dynamically set the "left" to anything.
The problem is that the HTML gets more verbose, which I'd like to avoid, plus I'd like to have control of how the dropdown appears to prevent it from being drawn off the screen.
But it seems like I've run into a problem that's impossible to solve, since I can not find anywhere a way to detect elements using "absolute" to be positioned.
Is there anything similar to "element.position" that gives me this information?
You asked for a way to detect position: absolute on elements.
Use window.getComputedStyle(element).position.
function findAbsoluteElementsFromList(list){
var ret = [];
for (var i = 0; i < list.length; i++)
if (window.getComputedStyle(list[i]).position === 'absolute')
ret.push(list[i]);
return ret;
}
console.log(findAbsoluteElementsFromList(document.querySelectorAll('div')));
.div {
width: 100px;
height: 100px;
position: absolute;
top: 0;
transform: translateY(50%);
}
#a {
position: relative;
left: 0;
background-color: #f00;
}
#b {
left: 25px;
background-color: #0f0;
}
#c {
left: 50px;
background-color: #00f;
}
<div class="div" id="a">
<div class="div" id="b">
<div class="div" id="c"></div>
</div>
</div>
Same function can be used to get all other CSS values.
What's the difference between Window.getComputedStyle and Element.getBoundingClientRect()? Read here.
Why can't you just use element.style.position? Read here.
According to https://www.w3schools.com/css/css_positioning.asp,
An element with position: absolute; is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed).
How can I get the nearest positioned ancestor of an Element, in either vanilla Javascript or JQuery?
What about offsetParent()? https://api.jquery.com/offsetParent/
Description: Get the closest ancestor element that is positioned.
You can test if the position is static of the parent, if not you continue until your reach the first ancestor with position different from static.
Here is a simplified code that you can adjust:
$('.box').each(function() {
var p = $(this).parent();
while (p && p.css('position') === 'static') {
p = p.parent();
}
console.log(p.attr('class'));
})
.box {
position: absolute;
}
.f2 {
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="f1">
<div class="f2">
<div class="f3">
<div class="box"> <!-- This one relative to f2 -->
<div class="box"> <!-- This one relative to box -->
</div>
</div>
</div>
</div>
</div>
<div class="f1">
<div class="f2">
<div class="f3" style="position:absolute;">
<div class="box"> <!-- This one relative to f3 -->
</div>
</div>
</div>
</div>
Edit : I was assuming you were looking for distance bewteen two elements. #TemaniAfif has the right answer
You could navigate the tree of ancestors using parentNode and compare the offsetTop of each to the offsetTop of the element at hand. if all you are interested in is the Y distance.
On the other hand if you need the full distance while accounting for X and Y, you could use the method described here
Measure distance between two HTML elements' centers
Here is my html look :
<div class="right fly" style="top: 45px;">
<div class="dataContainer">
<div class="fuelLvlInfo">
<div class="header"><i class="ion-arrow-down-b"></i>Paliwo - poziomowskaz</div>
<ul>
<li class="usage"><div class="n"><span>Zużycie [l]:</span></div><div class="v">24</div></li>
<li class="lvl"><div class="n"><span>Poziom paliwa [l]:</span></div><div class="v">---</div></li>
<li class="avgUsageKm"><div class="n"><span>Śr. zużycie [l/100km]:</span></div><div class="v">46.4</div></li>
<li class="avgUsageHour"><div class="n"><span>Śr. zużycie [l/h]:</span></div><div class="v">---</div></li>
</ul>
</div>
<div class="fuelflowInfo">
<div class="header"><i class="ion-arrow-down-b"></i>Paliwo - przepływomierz</div>
<ul>
<li class="usage"><div class="n"><span>Zużycie [l]:</span></div><div class="v">1</div></li>
<li class="avgUsageKm"><div class="n"><span>Śr. zużycie [l/100km]:</span></div><div class="v">1.9</div></li>
<li class="avgUsageHour"><div class="n"><span>Śr. zużycie [l/h]:</span></div><div class="v">---</div></li>
<li class="counter"><div class="n"><span>Licznik [l]:</span></div><div class="v">---</div></li>
</ul>
</div>
</div>
Here is preview:
What i need: make to .right be auto width, and divs in li must be 50% width or width equal to the longest div.n content.
Tried white-space:nowrap; display:inline-block etc. not working.
https://jsfiddle.net/eta71Lbx/
Preview what i expect :
50% width
or width fixed to content length (on left side or right side)
You're using the span element that will shrink the with based on the content. I would avoid using span.
But if you need to use it, then here is a work around to solve the .right part of the menu using jQuery.
Remove the 50% at the > div { width:50%; }
Add white-space:nowrap; to
the .n class.
(If you already included jQuery after the list is created, then
don't do this step). Include jQuery:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js">
Add the folowing to the ready or inside a function you want:
$(document).ready(function() {var maxWidth = 0;$( "li .n" ).each(function( index ) {var w = parseInt($(this).css('width').replace('px', ''));if(maxWidth<w){maxWidth = w;}});var m = maxWidth + 'px';$( ".n" ).css('width', m);});
https://jsfiddle.net/eta71Lbx/3/
Hope that helps!
G'day!
I have a page which has Horizontally Scroll feature going on there.
I have a side bar and a content box
In side bar I have 5 links, say LINK1 - LINK5
In the content box, I have 3500px of width which contains 5 sections of divs of 700px each.
So the page initially loads in the first 700px div. So if I click on Link 3, it will smoothly scrolling to 3rd div section.
However, I would like to load the page in the 2nd div.
I was able to do this using scrollLeft()
<script>$("div.content1").scrollLeft(700);</script>
But the horizontal scrolling will be messed up. The second div will act as first div, which means when I click LINK1, it won't be scrolled back.
Help?
*I think this code is needed
<script>
function goto(id, t){
//animate to the div id
$(".contentbox-wrapper").stop().animate({"left": -($(id).position().left)}, 1200);
}
</script>
This is sample of HTML code
<div id="sidebar1">
<span class="upper">Foods</span><br />
<span class="lower">Rice, Noodles & Pasta</span><br />
<span class="lower">Snacks & Tidbits</span><br />
<span class="lower">Canned & Ready to Eat</span><br />
<span class="lower">Breakfast Cereal</span><br />
<br />
This is sample of my content box
<div class="content1">
<div class="contentbox-wrapper">
<div id="rice" class="contentbox" align="center">
<h2>
Rice, Noodles & Pasta
</h2>
<section id="product">
<ul class="clear">
<li data-id="1">
<div href="#">
<img src="images/products/f1/_DSC4640.jpg" width="200" height="200" />
<h3>Maggi Curry Flavour</h3>
<p>(5 + 1) x 79 G</p>
<h2>Price:$2.40</h2>
</div>
</li>
I've created an example based a little on your markup. I hope, that it is, what you're looking for. I also made some minor changes on your JavaScript. See the explanation below.
HTML
<nav>
<a>Item 1</a>
<a>Item 2</a>
</nav>
<div class="contentbox-wrapper">
<div>
<h2>Item 1</h2>
</div>
<div>
<h2>Item 2</h2>
</div>
</div>
If you can apply a markup like this, where the index of each link corresponds with the index of each content container, then you can get rid of all the ids that you need in the JavaScript part.
CSS
div.contentbox-wrapper {
position: relative;
width: 400px;
height: 200px;
overflow: hidden;
overflow-x: scroll;
font-size: 0;
line-height: 0;
white-space: nowrap;
}
div.contentbox-wrapper > div {
display: inline-block;
width: 400px;
height: 200px;
text-align: center;
}
div.contentbox-wrapper > div:last-child {
margin-right: 0;
}
JavaScript
var container = $('div.contentbox-wrapper');
var boxes = container.children();
$('nav > a').click(function() {
container.stop().animate({
scrollLeft: boxes.eq($(this).index()).get(0).offsetLeft
}, 350);
});
Try to store selectors that you use multiple times in variables. The advantage is, that you don't need to re-query them again. This JavaScript does nothing else, then getting the offset of the box that corresponds with the clicked link, using .index() and .eq(). This value is then used in the .animate()-function to scroll to this position.
Demo
Try before buy
A few notes
If you have an ampersand within normal content like "Rice, Noodles & Pasta" you must escape it like: &.
Don't use align="center". It is deprecated since HTML4. Use CSS for this purpose.
i am adding divs dynamically at the bottom of screen. My problem is i want to add a div to left side of 1st div as used in facebook chatting.
I have created a jsfiddle example for more clarification
http://jsfiddle.net/Jsu4t/
<div id="ctrId1" class="draggable chatRoom " rel="0" style="float: right; bottom: 0; position:fixed; right: 0px; z-index: 1000; padding: 5px; background-color:whitesmoke;">
<div class="header" style="background-color:#006dcc">
<div style="float:right;">
<img id="imgDelete" class="imgClose" data-control="ctrId1" style="cursor:pointer;" src="Images/x_icon_hover.png"/></div>
<span class="selText" rel="0">rashmi</span></div>
<div id="divMessage" class="messageArea"></div>
<div class="buttonBar" style="padding-top:10px;bottom:0px,position:absolute;"><input id="txtPrivateMessage" class="msgText" type="text" />
<input id="btnSendMessage" class="submitButton button" type="button" value="Send" /></div></div>
In my code i am appending all the dynamic divs to a parent div, but still same issue.
you can append multiple DIVs to first DIV, there are two way to keep all div in a single line starting from left.
You can use "display:inline" Or you can use "float:left" in DIV style.
This one works as expected I hope
jsfiddle.net/U2QDD/