我想知道如何获得HTML元素的X和Y位置,例如img
和div
JavaScript.
正确的方法是使用element.getBoundingClientRect()
:
var rect = element.getBoundingClientRect(); console.log(rect.top, rect.right, rect.bottom, rect.left);
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 ');
这些库会花费一些时间来获得元素的准确偏移量.
这是一个简单的功能,可以在我尝试的每种情况下完成工作.
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;
这对我有用(从最高投票答案修改):
function getOffset(el) { const rect = el.getBoundingClientRect(); return { left: rect.left + window.scrollX, top: rect.top + window.scrollY }; }
使用这个我们可以打电话
getOffset(element).left
要么
getOffset(element).top
如果你想只在javascript中完成它.比这里有一个衬里.它的简单和易于使用getBoundingClientRect()
window.scrollX + document.querySelector('#elementId').getBoundingClientRect().left // X window.scrollY + document.querySelector('#elementId').getBoundingClientRect().top // Y
大多数浏览器上的HTML元素都有: -
offsetLeft offsetTop
这些指定了元素相对于具有布局的最近父元素的位置.通常可以通过offsetParent属性访问此父级.
IE和FF3都有
clientLeft clientTop
这些属性不太常见,它们使用其父客户区指定元素位置(填充区域是客户区域的一部分,但边界和边距不是).
如果页面包含 - 至少 - 任何"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]; };
您可以添加两个属性以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 );
}
} );
这被称为:
var x = document.getElementById( 'myDiv' ).documentOffsetLeft;
这里的比较结果以jQuery的演示offset().top
和.left
:http://jsfiddle.net/ThinkingStiff/3G7EZ/
要有效地检索相对于页面的位置,而不使用递归函数:(也包括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;
这样的事情,通过传递元素的ID,它将返回左侧或顶部,我们也可以组合它们:
1)找到左边
function findLeft(element) { var rec = document.getElementById(element).getBoundingClientRect(); return rec.left + window.scrollX; } //call it like findLeft('#header');
2)找到顶部
function findTop(element) { var rec = document.getElementById(element).getBoundingClientRect(); return rec.top + window.scrollY; } //call it like findTop('#header');
或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');
使用JavaScript框架可以提供更好的服务,该框架具有以独立于浏览器的方式返回此类信息(以及更多!)的功能.以下是一些:
原型
jQuery的
MooTools的
YUI(雅虎)
使用这些框架,您可以执行以下操作:
$('id-of-img').top
获取图像的y像素坐标.
jQuery .offset()将获取第一个元素的当前坐标,或者在匹配元素集中相对于文档设置每个元素的坐标.
我接受了@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 }; }
如果你仍然遇到问题,尤其是滚动问题,可以尝试查看http://www.greywyvern.com/?post=331 - 我注意到getStyle中至少有一段有问题的代码,假设浏览器的行为应该没问题,但还没有测试其余的.
如果使用jQuery,维度插件非常好,并允许您准确指定您想要的.
例如
相对位置,绝对位置,无填充的绝对位置,带衬垫......
它继续,让我们说你可以做很多事情.
此外,使用jQuery的好处是它的文件很轻,易于使用,之后如果没有它,你就不会再回到JavaScript了.
如果您使用的是jQuery,这可能是一个简单的解决方案:
这是我设法创建的最好的代码(也可以在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 }; }
小与小的区别
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 }; }
查看示例坐标: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;
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 = "" + rectLeft + ", " + rectTop + "";
}
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;
}
我是这样做的,因此它与旧浏览器交叉兼容.
// 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; }
有关JavaScript中坐标的更多信息,请访问:http://javascript.info/tutorial/coordinates