Wie kann ich den Offset eines Containers relativ zu einem Elternteil mit reinem JS abrufen?
Position/Offset des Elements relativ zu einem übergeordneten Container abrufen?
matt
Jackwander
element.offsetLeft
und element.offsetTop
geben die Position eines Elements in Bezug auf seine an offsetParent
(das ist das nächste übergeordnete Element mit einer Position von relative
oder absolute
.)
-
Element ist positioniert
static
sind keine versetzten Eltern.– Esailija
24. Juli 2012 um 16:05 Uhr
-
Verwenden Sie keine Semikolons in geschweiften Klammern, verwenden Sie Kommas
– Luca Borrione
21. Juni 2013 um 16:28 Uhr
-
Was ist mit der Position fixiert? Sind sie versetzte Eltern?
– Ayyash
28. April 2014 um 5:48 Uhr
-
Ja, @Ayya- position fixed erstellt auch einen neuen Offset-Kontext
– mmmeff
7. Mai 2015 um 21:10 Uhr
-
@vsync jQuery ist nicht der König von irgendetwas, seit ie9 im Januar 2016 EOL erreicht hat, haben wir eine standardisierte DOM-Auswahl in allen gängigen Browsern, lernen Sie reines js. Auch Meinungen darüber, welches Framework verwendet werden soll, haben bei SO keinen Platz, da es stark vom Projekt und der Zielplattform abhängt.
– Hans Koch
16. März 2018 um 7:34 Uhr
Fabrizio Calderán
in reinem js einfach verwenden offsetLeft
und offsetTop
Eigenschaften.
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>
-
Vielen Dank. Gibt es auch eine Möglichkeit, den Offset zu einem parent.parent-Element zu bekommen?
– matt
24. Juli 2012 um 16:09 Uhr
-
p.offsetTop + p.parentNode.offsetTop
Sie könnten dies viel in einen rekursiven Funktionsaufruf packen wie PPK vorgeschlagen vor einigen Jahren. Sie können die Funktion ändern, um entweder die Anzahl der Ebenen zu übergeben, um nach oben zu gehen, oder einen Selektor zum Nachahmen verwenden$(selector).parents(parentSelector)
. Ich würde diese Lösung bevorzugen, da die zepto-Implementierung nur auf Browsern funktioniert, die dies unterstützengetBoundingClientsRect
– was einige Handys nicht tun.– Thorsten Walter
24. Juli 2012 um 21:21 Uhr
-
ich dachte
getBoundingClientsRect
wurde weitgehend unterstützt … wenn jemand weiß, welche Handys es nicht unterstützen, wäre ich interessiert (kann keine Support-Tabelle für Handys darüber finden).– Aurelio
1. Juli 2014 um 11:54 Uhr
-
Dies ist wahrscheinlich die richtigste Antwort, auch wenn sie nicht markiert ist. Meine persönliche Lösung änderte sich
$(this).offset().left
zuthis.offsetLeft
.– adjwilli
6. August 2014 um 15:10 Uhr
-
Dies behebt auch Fehler
jQuery.position()
Verhalten innerhalb eines 3D-transformierten Elternteils, vielen Dank!– rassoh
3. Dezember 2017 um 15:05 Uhr
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;
Imran Ansari
Ich habe es so im Internet Explorer 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;
};
=================== so kann man es nennen
getWindowRelativeOffset(top, inputElement);
Ich konzentriere mich nur gemäß meinem Fokus auf IE, aber ähnliche Dinge können für andere Browser getan werden.
Irshad Khan
Beispiel
Wenn wir also ein untergeordnetes Element mit der ID „child-element“ hätten und wir seine linke/obere Position relativ zu einem übergeordneten Element erhalten wollten, sagen wir ein div mit der Klasse „item-parent“, würden wir das tun Verwenden Sie diesen Code.
var position = $("#child-element").offsetRelative("div.item-parent");
alert('left: '+position.left+', top: '+position.top);
Plugin Schließlich zum eigentlichen Plugin (mit ein paar Anmerkungen, die erklären, was vor sich geht):
// 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));
Notiz : Sie können verwenden Dies on mouseClick oder mouseover Event
$(this).offsetRelative("div.item-parent");
-
Ich sehe nicht, dass Scrollen berücksichtigt wird. Es gibt viele seltsame Fälle, die passieren können.
– David Spector
7. Dezember 2018 um 1:04 Uhr
-
jquery.min.js:2 Uncaught RangeError: Maximale Call-Stack-Größe überschritten. Dies ist der Fehler, der ausgelöst wird
– UJ Indien
21. Dezember 2021 um 12:46 Uhr
DeiDei
Fügen Sie den Offset des Ereignisses zum Offset des übergeordneten Elements hinzu, um die absolute Offset-Position 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, in dem das Ereignis registriert wurde, wird der Versatz des übergeordneten Elements zum aktuellen Ereignisversatz addiert, um den „absoluten“ Versatzwert zu berechnen.
Laut Mozilla Web API: „The HTMLElement.offsetLeft Die schreibgeschützte Eigenschaft gibt die Anzahl der Pixel zurück, die die obere linke Ecke des aktuellen Elements beträgt Versatz nach links innerhalb des HTMLElement.offsetParent-Knotens.“
Dies geschieht meistens, wenn Sie ein Ereignis auf einem übergeordneten Element registriert haben, das mehrere weitere untergeordnete Elemente enthält, z. B.: eine Schaltfläche mit einem inneren Symbol oder einer Textspanne, an li
Element mit inneren Spannweiten. etc…
-
Ich sehe nicht, dass Scrollen berücksichtigt wird. Es gibt viele seltsame Fälle, die passieren können.
– David Spector
7. Dezember 2018 um 1:04 Uhr
-
jquery.min.js:2 Uncaught RangeError: Maximale Call-Stack-Größe überschritten. Dies ist der Fehler, der ausgelöst wird
– UJ Indien
21. Dezember 2021 um 12:46 Uhr
Moises Conejo
Sicher ist es einfach mit reinem JS, tun Sie dies einfach, arbeiten Sie auch für feste und animierte HTML 5-Panels, ich habe diesen Code erstellt und ausprobiert und er funktioniert für jeden Browser (einschließlich 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>
-
Haben Sie mit allen möglichen Fällen von übergeordneten Knoten und Elementeigenschaften getestet? Berücksichtigt dies das Scrollen und das verschachtelte Scrollen?
– David Spector
7. Dezember 2018 um 1:03 Uhr