And*_*y E 1672
正确的方法是使用element.getBoundingClientRect():
var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);
Run Code Online (Sandbox Code Playgroud)
Internet Explorer已经支持这个,因为只要你可能关心它,它最终在CSSOM Views中被标准化.所有其他浏览器很久以前就采用了它.
某些浏览器还返回高度和宽度属性,但这不是标准的.如果您担心较旧的浏览器兼容性,请查看此答案的修订版,以获得优化的降级实现.
返回的值element.getBoundingClientRect()相对于视口.如果您需要它相对于另一个元素,只需从另一个元素中减去一个矩形:
var bodyRect = document.body.getBoundingClientRect(),
elemRect = element.getBoundingClientRect(),
offset = elemRect.top - bodyRect.top;
alert('Element is ' + offset + ' vertical pixels from <body>');
Run Code Online (Sandbox Code Playgroud)
meo*_*ouw 310
这些库会花费一些时间来获得元素的准确偏移量.
这是一个简单的功能,可以在我尝试的每种情况下完成工作.
function getOffset( el ) {
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return { top: _y, left: _x };
}
var x = getOffset( document.getElementById('yourElId') ).left;
Run Code Online (Sandbox Code Playgroud)
Ada*_*ant 212
这对我有用(从最高投票答案修改):
function getOffset(el) {
const rect = el.getBoundingClientRect();
return {
left: rect.left + window.scrollX,
top: rect.top + window.scrollY
};
}
Run Code Online (Sandbox Code Playgroud)
使用这个我们可以打电话
getOffset(element).left
Run Code Online (Sandbox Code Playgroud)
要么
getOffset(element).top
Run Code Online (Sandbox Code Playgroud)
Amj*_*d K 56
如果你想只在javascript中完成它.比这里有一个衬里.它的简单和易于使用getBoundingClientRect()
window.scrollX + document.querySelector('#elementId').getBoundingClientRect().left // X
window.scrollY + document.querySelector('#elementId').getBoundingClientRect().top // Y
Run Code Online (Sandbox Code Playgroud)
第一行将返回offsetLeft,表示相对于文档的X.
并且第二行将返回offsetTop, 表示Y相对于文档
getBoundingClientRect()是一个javascript函数,它返回元素相对于窗口视口的位置.
Ant*_*nes 42
大多数浏览器上的HTML元素都有: -
offsetLeft
offsetTop
Run Code Online (Sandbox Code Playgroud)
这些指定了元素相对于具有布局的最近父元素的位置.通常可以通过offsetParent属性访问此父级.
IE和FF3都有
clientLeft
clientTop
Run Code Online (Sandbox Code Playgroud)
这些属性不太常见,它们使用其父客户区指定元素位置(填充区域是客户区域的一部分,但边界和边距不是).
小智 35
如果页面包含 - 至少 - 任何"DIV",则由meouw给出的函数会抛出超出当前页面限制的"Y"值.为了找到确切的位置,您需要同时处理offsetParent和parentNode.
尝试下面给出的代码(检查FF2):
var getAbsPosition = function(el){
var el2 = el;
var curtop = 0;
var curleft = 0;
if (document.getElementById || document.all) {
do {
curleft += el.offsetLeft-el.scrollLeft;
curtop += el.offsetTop-el.scrollTop;
el = el.offsetParent;
el2 = el2.parentNode;
while (el2 != el) {
curleft -= el2.scrollLeft;
curtop -= el2.scrollTop;
el2 = el2.parentNode;
}
} while (el.offsetParent);
} else if (document.layers) {
curtop += el.y;
curleft += el.x;
}
return [curtop, curleft];
};
Run Code Online (Sandbox Code Playgroud)
Thi*_*iff 35
您可以添加两个属性以Element.prototype获取任何元素的顶部/左侧.
Object.defineProperty( Element.prototype, 'documentOffsetTop', {
get: function () {
return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
}
} );
Object.defineProperty( Element.prototype, 'documentOffsetLeft', {
get: function () {
return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
}
} );
Run Code Online (Sandbox Code Playgroud)
这被称为:
var x = document.getElementById( 'myDiv' ).documentOffsetLeft;
Run Code Online (Sandbox Code Playgroud)
这里的比较结果以jQuery的演示offset().top和.left:http://jsfiddle.net/ThinkingStiff/3G7EZ/
Abd*_*dad 22
要有效地检索相对于页面的位置,而不使用递归函数:(也包括IE)
var element = document.getElementById('elementId'); //replace elementId with your element's Id.
var rect = element.getBoundingClientRect();
var elementLeft,elementTop; //x and y
var scrollTop = document.documentElement.scrollTop?
document.documentElement.scrollTop:document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft?
document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;
Run Code Online (Sandbox Code Playgroud)
Phi*_*ipp 21
这是一个现代的 1-liner,使用 vanilla JS 递归地迭代element.offsetTopand element.offsetParent:
功能:
getTop = el => el.offsetTop + (el.offsetParent && getTop(el.offsetParent))
Run Code Online (Sandbox Code Playgroud)
用法:
const el = document.querySelector('#div_id');
const elTop = getTop(el)
Run Code Online (Sandbox Code Playgroud)
优势:
无论当前滚动位置如何,始终返回绝对垂直偏移。
传统语法:
function getTop(el) {
return el.offsetTop + (el.offsetParent && getTop(el.offsetParent));
}
Run Code Online (Sandbox Code Playgroud)
Ali*_*eza 19
这样的事情,通过传递元素的ID,它将返回左侧或顶部,我们也可以组合它们:
1)找到左边
function findLeft(element) {
var rec = document.getElementById(element).getBoundingClientRect();
return rec.left + window.scrollX;
} //call it like findLeft('#header');
Run Code Online (Sandbox Code Playgroud)
2)找到顶部
function findTop(element) {
var rec = document.getElementById(element).getBoundingClientRect();
return rec.top + window.scrollY;
} //call it like findTop('#header');
Run Code Online (Sandbox Code Playgroud)
或3)找到左边和顶部
function findTopLeft(element) {
var rec = document.getElementById(element).getBoundingClientRect();
return {top: rec.top + window.scrollY, left: rec.left + window.scrollX};
} //call it like findTopLeft('#header');
Run Code Online (Sandbox Code Playgroud)
Sha*_*mer 17
使用JavaScript框架可以提供更好的服务,该框架具有以独立于浏览器的方式返回此类信息(以及更多!)的功能.以下是一些:
使用这些框架,您可以执行以下操作:
$('id-of-img').top
获取图像的y像素坐标.
Văn*_*yết 12
/**
*
* @param {HTMLElement} el
* @return {{top: number, left: number}}
*/
function getDocumentOffsetPosition(el) {
var position = {
top: el.offsetTop,
left: el.offsetLeft
};
if (el.offsetParent) {
var parentPosition = getDocumentOffsetPosition(el.offsetParent);
position.top += parentPosition.top;
position.left += parentPosition.left;
}
return position;
}
Run Code Online (Sandbox Code Playgroud)
感谢ThinkingStiff的答案,这只是另一个版本。
Jam*_*rke 10
我接受了@meouw的回答,在允许边框的clientLeft中添加了,然后创建了三个版本:
getAbsoluteOffsetFromBody - 类似于@meouw's,它获取相对于文档的body或html元素的绝对位置(取决于quirks模式)
getAbsoluteOffsetFromGivenElement - 返回相对于给定元素的绝对位置(relativeEl).请注意,给定元素必须包含元素el,否则其行为与getAbsoluteOffsetFromBody相同.如果您有两个元素包含在另一个(已知)元素(可选择在节点树中的几个节点)并希望使它们位于相同位置,则此选项非常有用.
getAbsoluteOffsetFromRelative - 返回相对于第一个父元素的绝对位置,其位置为:relative.这与getAbsoluteOffsetFromGivenElement类似,出于同样的原因,但只会到第一个匹配元素.
getAbsoluteOffsetFromBody = function( el )
{ // finds the offset of el from the body or html element
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
{
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;
}
return { top: _y, left: _x };
}
getAbsoluteOffsetFromGivenElement = function( el, relativeEl )
{ // finds the offset of el from relativeEl
var _x = 0;
var _y = 0;
while( el && el != relativeEl && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
{
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;
}
return { top: _y, left: _x };
}
getAbsoluteOffsetFromRelative = function( el )
{ // finds the offset of el from the first parent with position: relative
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
{
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;
if (el != null)
{
if (getComputedStyle !== 'undefined')
valString = getComputedStyle(el, null).getPropertyValue('position');
else
valString = el.currentStyle['position'];
if (valString === "relative")
el = null;
}
}
return { top: _y, left: _x };
}
Run Code Online (Sandbox Code Playgroud)
如果你仍然遇到问题,尤其是滚动问题,可以尝试查看http://www.greywyvern.com/?post=331 - 我注意到getStyle中至少有一段有问题的代码,假设浏览器的行为应该没问题,但还没有测试其余的.
如果您使用的是jQuery,这可能是一个简单的解决方案:
<script>
var el = $("#element");
var position = el.position();
console.log( "left: " + position.left + ", top: " + position.top );
</script>
Run Code Online (Sandbox Code Playgroud)
这是我设法创建的最好的代码(也可以在iframe中工作,与jQuery的offset()不同).似乎webkit有一些不同的行为.
根据meouw的评论:
function getOffset( el ) {
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
// chrome/safari
if ($.browser.webkit) {
el = el.parentNode;
} else {
// firefox/IE
el = el.offsetParent;
}
}
return { top: _y, left: _x };
}
Run Code Online (Sandbox Code Playgroud)
小与小的区别
function getPosition( el ) {
var x = 0;
var y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
x += el.offsetLeft - el.scrollLeft;
y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return { top: y, left: x };
}
Run Code Online (Sandbox Code Playgroud)
查看示例坐标:http: //javascript.info/tutorial/coordinates
我发现最干净的方法是jQuery使用的技术的简化版本offset.与其他一些答案类似,它始于getBoundingClientRect; 然后使用window和documentElement调整滚动位置以及边距body(通常是默认值).
var rect = el.getBoundingClientRect();
var docEl = document.documentElement;
var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;
Run Code Online (Sandbox Code Playgroud)
var els = document.getElementsByTagName("div");
var docEl = document.documentElement;
for (var i = 0; i < els.length; i++) {
var rect = els[i].getBoundingClientRect();
var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;
els[i].innerHTML = "<b>" + rectLeft + ", " + rectTop + "</b>";
}Run Code Online (Sandbox Code Playgroud)
div {
width: 100px;
height: 100px;
background-color: red;
border: 1px solid black;
}
#rel {
position: relative;
left: 10px;
top: 10px;
}
#abs {
position: absolute;
top: 250px;
left: 250px;
}Run Code Online (Sandbox Code Playgroud)
<div id="rel"></div>
<div id="abs"></div>
<div></div>Run Code Online (Sandbox Code Playgroud)
虽然这很可能会在这么多答案的底部丢失,但这里的最佳解决方案对我不起作用。
据我所知,其他任何答案都没有帮助。
情况:
在 HTML5 页面中,我有一个菜单,它是标题中的导航元素(不是标题,而是另一个元素中的标题)。
我希望导航在用户滚动到它时粘在顶部,但在此之前,标题是绝对定位的(所以我可以让它稍微覆盖其他东西)。
上面的解决方案从未触发更改,因为 .offsetTop 不会更改,因为这是一个绝对定位的元素。此外 .scrollTop 属性只是最顶部元素的顶部......也就是说 0 并且始终为 0。
我使用这两个(与 getBoundingClientRect 结果相同)执行的任何测试都不会告诉我导航栏的顶部是否曾经滚动到可查看页面的顶部(同样,如控制台中所报告的那样,它们只是在滚动时保持相同的数字发生了)。
解决
方案我的解决方案是利用
window.visualViewport.pageTop
Run Code Online (Sandbox Code Playgroud)
pageTop 属性的值反映了屏幕的可查看部分,因此允许我根据可查看区域的边界跟踪元素所在的位置。
可能没有必要说,每当我处理滚动时,我都希望使用此解决方案以编程方式响应正在滚动的元素的移动。
希望它可以帮助别人。
重要说明:这似乎目前在 Chrome 和 Opera 中有效,绝对不能在 Firefox (6-2018) 中使用......直到 Firefox 支持visualViewport 我建议不要使用这种方法,(我希望他们很快这样做......它做了很多比其他的更有意义)。
更新:
只是关于此解决方案的说明。
虽然我仍然发现我发现的对于“......以编程方式响应滚动元素的移动”的情况非常有价值。适用。我遇到的问题的更好解决方案是使用 CSS 来设置position:sticky在元素上。使用粘性,您可以在不使用 javascript 的情况下让元素保持在顶部(注意:有时这不会像将元素更改为固定那样有效,但对于大多数用途,粘性方法可能会更好)
UPDATE01:
所以我意识到对于不同的页面,我有一个要求,我需要在稍微复杂的滚动设置中检测元素的位置(视差加上作为消息一部分滚动过去的元素)。在那个场景中,我意识到以下提供了我用来确定何时做某事的价值:
let bodyElement = document.getElementsByTagName('body')[0];
let elementToTrack = bodyElement.querySelector('.trackme');
trackedObjPos = elementToTrack.getBoundingClientRect().top;
if(trackedObjPos > 264)
{
bodyElement.style.cssText = '';
}
Run Code Online (Sandbox Code Playgroud)
希望这个答案现在更广泛有用。
要获得元素的总偏移量,您可以递归地总结所有父偏移量:
function getParentOffsets(el): number {
if (el.offsetParent) {
return el.offsetParent.offsetTop + getParentOffset(el.offsetParent);
} else {
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
使用此实用程序函数,dom 元素的总顶部偏移为:
el.offsetTop + getParentOffsets(el);
Run Code Online (Sandbox Code Playgroud)
我是这样做的,因此它与旧浏览器交叉兼容.
// For really old browser's or incompatible ones
function getOffsetSum(elem) {
var top = 0,
left = 0,
bottom = 0,
right = 0
var width = elem.offsetWidth;
var height = elem.offsetHeight;
while (elem) {
top += elem.offsetTop;
left += elem.offsetLeft;
elem = elem.offsetParent;
}
right = left + width;
bottom = top + height;
return {
top: top,
left: left,
bottom: bottom,
right: right,
}
}
function getOffsetRect(elem) {
var box = elem.getBoundingClientRect();
var body = document.body;
var docElem = document.documentElement;
var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
var clientTop = docElem.clientTop;
var clientLeft = docElem.clientLeft;
var top = box.top + scrollTop - clientTop;
var left = box.left + scrollLeft - clientLeft;
var bottom = top + (box.bottom - box.top);
var right = left + (box.right - box.left);
return {
top: Math.round(top),
left: Math.round(left),
bottom: Math.round(bottom),
right: Math.round(right),
}
}
function getOffset(elem) {
if (elem) {
if (elem.getBoundingClientRect) {
return getOffsetRect(elem);
} else { // old browser
return getOffsetSum(elem);
}
} else
return null;
}
Run Code Online (Sandbox Code Playgroud)
有关JavaScript中坐标的更多信息,请访问:http://javascript.info/tutorial/coordinates
小智 5
Run Code Online (Sandbox Code Playgroud)
HTML program to show (x, y) of an
element by dragging mouse over it you just copied it and use it on your own
<!DOCTYPE html>
<html>
<head>
<title>
position of an element
</title>
<!-- scropt to get position -->
<script type = "text/javascript">
function getPositionXY(element) {
var rect = element.getBoundingClientRect();
document.getElementById('text').innerHTML
= 'X: ' + rect.x + '<br>' + 'Y: ' + rect.y;
}
</script>
</head>
<body>
<p>Move the mouse over the text</p>
<div onmouseover = "getPositionXY(this)">
Position:
<p id = 'text'></p>
</div>
</body>
</html> Run Code Online (Sandbox Code Playgroud)
小智 5
我可以只是喜欢element.offsetLeft或element.offsetTop。例子 :
document.getElementById('profileImg').offsetLeft
| 归档时间: |
|
| 查看次数: |
1288150 次 |
| 最近记录: |