获取元素相对于父容器的位置/偏移量?

我习惯于使用jQuery。 在我目前的项目中,我使用zepto.js。 Zepto不提供像jQuery那样的position()方法。 Zepto只带有offset()

任何想法如何检索一个容器相对于纯Js或Zepto的父母的偏移?

element.offsetLeftelement.offsetTop是用于查找元素相对于其offsetParent的位置的纯javascript属性; 是relativeabsolute位置最近的父元素

或者,你总是可以使用Zepto来获取元素的位置和它的父元素,并简单地减去这两个元素:

 var childPos = obj.offset(); var parentPos = obj.parent().offset(); var childOffset = { top: childPos.top - parentPos.top, left: childPos.left - parentPos.left } 

即使父母没有被定位,这也有利于给予孩子相对于父母的补偿。

在纯js中只需使用offsetLeftoffsetTop属性。
示例小提琴: http : //jsfiddle.net/WKZ8P/

 var elm = document.querySelector('span'); console.log(elm.offsetLeft, elm.offsetTop); 
 p { position:relative; left:10px; top:85px; border:1px solid blue; } span{ position:relative; left:30px; top:35px; border:1px solid red; } 
 <p> <span>paragraph</span> </p> 

我在Internet Explorer中这样做了。

 function getWindowRelativeOffset(parentWindow, elem) { var offset = { left : 0, top : 0 }; // relative to the target field's document offset.left = elem.getBoundingClientRect().left; offset.top = elem.getBoundingClientRect().top; // now we will calculate according to the current document, this current // document might be same as the document of target field or it may be // parent of the document of the target field var childWindow = elem.document.frames.window; while (childWindow != parentWindow) { offset.left = offset.left + childWindow.frameElement.getBoundingClientRect().left; offset.top = offset.top + childWindow.frameElement.getBoundingClientRect().top; childWindow = childWindow.parent; } return offset; }; 

===================你可以这样称呼它

 getWindowRelativeOffset(top, inputElement); 

我只专注于IE浏览器,但其他浏览器也可以做类似的事情。

所以,如果我们有一个id为“child-element”的子元素,我们想要得到它相对于父元素的左/顶位置,比如说一个具有“item-parent”类的div,使用这个代码。

 var position = $("#child-element").offsetRelative("div.item-parent"); alert('left: '+position.left+', top: '+position.top); 

插件最后,对于实际的插件(有几个笔记,展示了正在发生的事情):

 // offsetRelative (or, if you prefer, positionRelative) (function($){ $.fn.offsetRelative = function(top){ var $this = $(this); var $parent = $this.offsetParent(); var offset = $this.position(); if(!top) return offset; // Didn't pass a 'top' element else if($parent.get(0).tagName == "BODY") return offset; // Reached top of document else if($(top,$parent).length) return offset; // Parent element contains the 'top' element we want the offset to be relative to else if($parent[0] == $(top)[0]) return offset; // Reached the 'top' element we want the offset to be relative to else { // Get parent's relative offset var parent_offset = $parent.offsetRelative(top); offset.top += parent_offset.top; offset.left += parent_offset.left; return offset; } }; $.fn.positionRelative = function(top){ return $(this).offsetRelative(top); }; }(jQuery)); 

注意:你可以在mouseClick或mouseover Event上使用

 $(this).offsetRelative("div.item-parent"); 

将事件的偏移量添加到父元素偏移量以获取事件的绝对偏移位置。

一个例子 :

 HTMLElement.addEventListener('mousedown',function(e){ var offsetX = e.offsetX; var offsetY = e.offsetY; if( e.target != this ){ // 'this' is our HTMLElement offsetX = e.target.offsetLeft + e.offsetX; offsetY = e.target.offsetTop + e.offsetY; } } 

当事件目标不是事件注册的元素时,它会将父级的偏移量添加到当前事件偏移量中,以便计算“绝对”偏移量值。

根据Mozilla Web API:“ HTMLElement.offsetLeft只读属性返回当前元素的左上angular在HTMLElement.offsetParent节点左侧偏移的像素数

当你在包含多个子项的父项上注册事件时,主要发生这种情况,例如:带有内部图标或文本跨度的button,带有内部跨度的li元素。 等等…

当然,使用纯JS很容易,只要做到这一点,也适用于固定和animation的HTML 5面板,我做了这个代码,它适用于任何浏览器(包括IE 8):

 <script type="text/javascript"> function fGetCSSProperty(s, e) { try { return s.currentStyle ? s.currentStyle[e] : window.getComputedStyle(s)[e]; } catch (x) { return null; } } function fGetOffSetParent(s) { var a = s.offsetParent || document.body; while (a && a.tagName && a != document.body && fGetCSSProperty(a, 'position') == 'static') a = a.offsetParent; return a; } function GetPosition(s) { var b = fGetOffSetParent(s); return { Left: (b.offsetLeft + s.offsetLeft), Top: (b.offsetTop + s.offsetTop) }; } </script> 

我有另一个解决scheme。 从子属性值中减去父属性值

 $('child-div').offset().top - $('parent-div').offset().top;