我想知道如何在JavaScript中获取img和div等HTML元素的X和Y位置。
当前回答
要获得元素的总偏移量,可以递归地对所有父偏移量求和:
function getParentOffset(el): number {
if (el.offsetParent) {
return el.offsetParent.offsetTop + getParentOffset(el.offsetParent);
} else {
return 0;
}
}
使用该实用函数,dom元素的总顶部偏移量为:
el.offsetTop + getParentOffset(el);
其他回答
我是这样做的,所以它与旧浏览器兼容。
// 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
如果使用jQuery,维度插件非常出色,可以让您精确地指定所需内容。
e.g.
相对位置,绝对位置,无填充的绝对位置,有填充。。。
继续下去,让我们说你可以用它做很多事情。
另外,使用jQuery的好处是它的文件大小很小,使用起来很方便,以后如果没有它,就不会返回JavaScript。
由于不同的浏览器以不同的方式呈现边框、填充、边距等。我编写了一个小函数来检索每个根元素中特定元素的顶部和左侧位置,您需要精确的维度:
function getTop(root, offset) {
var rootRect = root.getBoundingClientRect();
var offsetRect = offset.getBoundingClientRect();
return offsetRect.top - rootRect.top;
}
对于检索左侧位置,必须返回:
return offsetRect.left - rootRect.left;
更新:
递归方法(在我以前的答案中)创建了许多调用堆栈。在这种情况下,我们可以使用while循环来避免递归:
/**
*
* @param {HTMLElement} el
* @return {{top: number, left: number}}
*/
function getDocumentOffsetPosition(el) {
let top = 0, left = 0;
while (el !== null) {
top += el.offsetTop;
left += el.offsetLeft;
el = el.offsetParent;
}
return {top, left};
}
旧答案:
/**
*
* @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;
}
感谢Thinkingtiff的回答,这只是另一个版本。
您可以将两个财产添加到Element.protype中,以获得任何元素的顶部/左侧。
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/
推荐文章
- 在数组中获取所有选中的复选框
- 如何为Firebase构建云函数,以便从多个文件部署多个函数?
- 如何发送推送通知到web浏览器?
- AngularJS:工厂和服务?
- js:将一个组件包装成另一个组件
- 我如何在网站上使用谷歌的Roboto字体?
- 父ng-repeat从子ng-repeat的访问索引
- 如何禁用文本区域大小调整?
- JSHint和jQuery: '$'没有定义
- 模仿JavaScript中的集合?
- 用JavaScript验证电话号码
- 如何在HTML5中改变视频的播放速度?
- 保留HTML字体大小时,iPhone的方向从纵向改变为横向
- 谷歌地图API v3:我可以setZoom后fitBounds?
- ES6/2015中的null安全属性访问(和条件赋值)