it-swarm.com.de

Position / Offset des Elements relativ zu einem übergeordneten Container ermitteln?

Ich bin es gewohnt, mit jQuery zu arbeiten. In meinem aktuellen Projekt verwende ich jedoch zepto.js. Zepto bietet keine position() -Methode wie jQuery. Zepto wird nur mit offset() ausgeliefert.

Irgendeine Idee, wie ich den Offset eines Containers relativ zu einem übergeordneten Objekt mit reinem js oder mit Zepto abrufen kann?

104
matt

Warnung: jQuery, kein Standard-JavaScript

element.offsetLeft und element.offsetTop sind die reinen Javascript-Eigenschaften zum Finden der Position eines Elements in Bezug auf sein offsetParent; Das nächste übergeordnete Element mit der Position relative oder absolute

Alternativ können Sie immer Zepto verwenden, um die Position eines Elements UND seines übergeordneten Elements abzurufen, und einfach die beiden subtrahieren:

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

Dies hat den Vorteil, dass Sie den Versatz eines Kindes relativ zu seinem Elternteil erhalten, auch wenn das Elternteil nicht positioniert ist.

182
jackwanders

verwenden Sie in reinen Js einfach die Eigenschaften offsetLeft und offsetTop.
Beispiel Geige: 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>
48
fcalderan

Ich habe es im Internet Explorer so gemacht.

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;
};

=================== Sie können es so nennen

getWindowRelativeOffset(top, inputElement);

Ich konzentriere mich nur auf IE nach meinem Fokus, aber ähnliche Dinge können für andere Browser durchgeführt werden.

5
Imran Ansari

Fügen Sie den Versatz des Ereignisses zum Versatz des übergeordneten Elements hinzu, um die absolute Versatzposition des Ereignisses zu erhalten.

Ein Beispiel :

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;

    }
}

Wenn das Ereignisziel nicht das Element ist, für das das Ereignis registriert wurde, addiert es den Versatz des übergeordneten Elements zum aktuellen Ereignisversatz, um den Versatzwert "Absolut" zu berechnen.

Laut Mozilla Web API: "Die schreibgeschützte Eigenschaft HTMLElement.offsetLeft gibt die Anzahl der Pixel zurück, die die linke obere Ecke des aktuellen Elements nach links versetzt innerhalb von HTMLElement.offsetParent) ist Knoten. "

Dies geschieht meistens, wenn Sie ein Ereignis auf einem übergeordneten Element registriert haben, das mehrere untergeordnete Elemente enthält, z. B. eine Schaltfläche mit einem inneren Symbol oder einem Textspann, ein li -Element mit inneren Feldern. usw...

1
levi

Ich habe eine andere Lösung. Subtrahieren Sie den Wert der übergeordneten Eigenschaft vom Wert der untergeordneten Eigenschaft

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

Beispiel

Wenn wir also ein untergeordnetes Element mit der ID "child-element" hätten und die Position "left/top" relativ zu einem übergeordneten Element erhalten möchten, sagen wir, ein div mit der Klasse "item-parent" benutze diesen Code.

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

Plugin Zum Schluss für das eigentliche Plugin (mit ein paar Anmerkungen, die erläutern, was los ist):

// 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));

Hinweis: Sie können dies für mouseClick- oder mouseover-Ereignisse verwenden

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

Sicher ist es einfach mit reinem JS, mach das einfach, arbeite auch für feste und animierte HTML 5 Panels, ich habe diesen Code gemacht und probiere ihn aus und er funktioniert für jeden Browser (include 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>
0
Moises Conejo