J'ai l'habitude de travailler avec jQuery. Cependant, dans mon projet actuel, j'utilise zepto.js. Zepto ne fournit pas de méthode position()
comme jQuery. Zepto vient uniquement avec offset()
.
Une idée de comment je peux récupérer le décalage d'un conteneur par rapport à un parent avec js pur ou avec Zepto?
element.offsetLeft
et element.offsetTop
sont les propriétés JavaScript pures permettant de rechercher la position d'un élément par rapport à sa offsetParent
; étant l'élément parent le plus proche avec une position de relative
ou absolute
Alternativement, vous pouvez toujours utiliser Zepto pour obtenir la position d'un élément ET de son parent, et soustrayez simplement les deux:
var childPos = obj.offset();
var parentPos = obj.parent().offset();
var childOffset = {
top: childPos.top - parentPos.top,
left: childPos.left - parentPos.left
}
Cela a l'avantage de vous donner le décalage d'un enfant par rapport à son parent même si le parent n'est pas positionné.
en js pur, utilisez simplement les propriétés offsetLeft
et offsetTop
.
Exemple de violon: 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>
Je l'ai fait comme ça dans 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;
};
=================== vous pouvez l'appeler comme ceci
getWindowRelativeOffset(top, inputElement);
Je me concentre sur IE uniquement selon mon objectif, mais des opérations similaires peuvent être effectuées pour d'autres navigateurs.
Ajoutez le décalage de l'événement au décalage de l'élément parent pour obtenir la position de décalage absolu de l'événement.
Un exemple :
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;
}
}
Lorsque la cible de l'événement n'est pas l'élément auquel l'événement a été enregistré, elle ajoute le décalage du parent au décalage de l'événement en cours afin de calculer la valeur de décalage "Absolue".
Selon l’API Web Mozilla: "La propriété HTMLElement.offsetLeft en lecture seule renvoie le nombre de pixels correspondant au coin supérieur gauche de l’élément actuel décalé vers la gauche dans HTMLElement.offsetParent noeud. "
Cela se produit généralement lorsque vous avez enregistré un événement sur un parent contenant plusieurs enfants supplémentaires, par exemple: un bouton avec une icône interne ou une plage de texte, un élément li
avec des plages internes. etc...
J'ai une autre solution. Soustraire la valeur de la propriété parent de la valeur de la propriété enfant
$('child-div').offset().top - $('parent-div').offset().top;
Exemple
Donc, si nous avions un élément enfant avec un id "élément-enfant" et que nous voulions le positionner à gauche/en haut par rapport à un élément parent, disons une div ayant une classe de "élément-parent", utilisez ce code.
var position = $("#child-element").offsetRelative("div.item-parent");
alert('left: '+position.left+', top: '+position.top);
Plugin Enfin, pour le plugin actuel (avec quelques notes expliquant ce qui se passe):
// 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));
Note: Vous pouvez utiliser this sur un événement mouseClick ou mouseover
$(this).offsetRelative("div.item-parent");
C’est simple avec JS pur, faites-le simplement, travaillez pour les panneaux HTML 5 fixes et animés aussi, j’ai créé et essayé ce code, qui fonctionne pour tous les navigateurs (inclure 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>