私はjQueryでの作業に慣れています。しかし、私の現在のプロジェクトでは、zepto.jsを使用しています。 Zeptoは、jQueryのようにposition()
メソッドを提供しません。 Zeptoにはoffset()
のみが付属しています。
純粋なjsまたはZeptoを使用して、親に対するコンテナのオフセットを取得する方法はありますか?
element.offsetLeft
とelement.offsetTop
は、offsetParent
に関して要素の位置を見つけるための純粋なjavascriptプロパティです。 relative
またはabsolute
の位置を持つ最も近い親要素であること
あるいは、常に Zepto を使用して、要素とその親の位置を取得し、単純に2つを減算することができます。
var childPos = obj.offset();
var parentPos = obj.parent().offset();
var childOffset = {
top: childPos.top - parentPos.top,
left: childPos.left - parentPos.left
}
これには、親が配置されていない場合でも、親に対する子のオフセットが提供されるという利点があります。
純粋なjsでは、offsetLeft
およびoffsetTop
プロパティを使用するだけです。
フィドルの例: 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に焦点を合わせていますが、他のブラウザでも同様のことができます。
イベントのオフセットを親要素のオフセットに追加して、イベントの絶対オフセット位置を取得します。
例 :
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読み取り専用プロパティは、現在の要素の左上隅がHTMLElement.offsetParent内で左にオフセットされているピクセル数を返しますnode。 "
これは主に、さらにいくつかの子を含む親にイベントを登録したときに発生します。たとえば、内側のアイコンまたはテキストスパンを持つボタン、内側のスパンを持つli
要素などです。等...
例
したがって、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));
注:使用できますthis mouseClickイベントまたはmouseoverイベント
$(this).offsetRelative("div.item-parent");
別の解決策を得ました。子プロパティ値から親プロパティ値を引きます
$('child-div').offset().top - $('parent-div').offset().top;
確かに、純粋なJSでは簡単です。これを行うだけで、修正およびアニメーション化された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>