Obtenir l' offset par rapport au premier parent positionné

Soyez le premier à donner votre avis sur cette source.

Snippet vu 7 699 fois - Téléchargée 17 fois

Contenu du snippet

Si vous utilisez element.offsetTop ou element.offsetLeft pour un élément, il n'y a pas deux navigateurs qui vous répondront la même chose.

Il semblerait que seul Firefox soit logique et renvoie l'Offset par rapport au premier parent positionné. Opera renvoie par rapport au premier parent, et IE par rapport au premier parent hiérarchique (mais malgré mes tests, je me demande encore quelle est sa définition d'un parent hiérachique...)

Le problème s'est posé pour moi quand j'ai voulu faire passer un élément d'une position statique à absolue, mais en le laissant exactement à la même position, il me fallait donc ses coordonnées par rapport au premier parent positionné. Et il m'a donc fallu écrire cette petite fonction, qui devrait renvoyer la même valeur avec tous les navigateurs.

Source / Exemple :


//donne la position par rapport à window
function getOffsetPosition(el_id, side){
	element = document.getElementById(el_id);

	newNode = document.createElement("div");
	newNode.innerHTML =  "<div style=\"height: 12px;\"></div>";
	element.insertBefore(newNode, element.firstChild);
	
	iVal = 0;
	oObj = element;
	var sType = "oObj.offset"+side;
	while (oObj && oObj.tagName != "html") {
		iVal += eval(sType);
		oObj = oObj.offsetParent;
	}
	element.removeChild(newNode);
	return iVal;
}

//donne la position par rapport au premier parent positionné
function getOffsetParentPosition(el_id, side){
	el_parent = document.getElementById(el_id).parentNode;
	while (el_parent) {
		if(navigator.appName != "Microsoft Internet Explorer"){
			if(window.getComputedStyle(el_parent,null).position == "relative" || window.getComputedStyle(el_parent,null).position == "absolute"){
				break;
			}
			else {
				if(el_parent.tagName != "HTML"){
					el_parent = el_parent.parentNode;
				}
				else {
					el_parent = null;
				}
			}
		}
		else {
			if(el_parent.currentStyle.position == "relative" || el_parent.currentStyle.position == "absolute"){
				break;
			}
			else {
				if(el_parent.tagName != "HTML"){
					el_parent = el_parent.parentNode;
				}
				else {
					el_parent = null;
				}
			}
		}
	}
	
	if(el_parent){ parentOffset = getOffsetPosition(el_parent.id, side); }
	else { parentOffset = 0; }
	return getOffsetPosition(el_id, side) - parentOffset;
}

/*
exemple d'utilisation :
<html>
<head>

<script>
	ici les 2 fonctions

	window.onload = function(){
		alert(getOffsetParentPosition("lau", "Top"));
		alert(getOffsetParentPosition("lau", "Left");
	}
</script>
</head>
<body>
	<div id="ff" style="padding-top: 65px; position: absolute;"><div id="lau"></div></div>
</body>
</html>

  • /

Conclusion :


Attention, le parent positionné doit avoir un id. Ou alors vous devrez modifier la première fonction pour qu'elle accepte aussi des éléments et pas seulement un id comme premier paramètre (c'est simple à faire :) )

Si l'élément passé à la fonction ne comporte pas d'enfants qui ont du margin-top, vous voudrez sans doute enlever le mécanisme DOM de la première fonction, cela ralentit le script.

Merci à Bultez pour son aide sur .currentStyle et getComputedStyle :)

A voir également

Ajouter un commentaire

Commentaires

Messages postés
626
Date d'inscription
samedi 28 septembre 2002
Statut
Membre
Dernière intervention
18 mai 2009
3
hô ! bon désolé ^^
Messages postés
1980
Date d'inscription
dimanche 20 février 2005
Statut
Membre
Dernière intervention
24 septembre 2012
5
Je pense que tu n'as lu ni le titre, ni les explications, ni ma source : OBTENIR L' OFFSET PAR RAPPORT AU ***PREMIER PARENT POSITIONNÉ***.
Messages postés
626
Date d'inscription
samedi 28 septembre 2002
Statut
Membre
Dernière intervention
18 mai 2009
3
Je n'ai peut-être pas vraiment compris le but de ta source mais perso, pour trouver l'offset exact d'un element dans sa page j'utilise la fonction suivante :


function getOffsets(obj) {
var offsetTop = obj.offsetTop;
var offsetLeft = obj.offsetLeft;
while ((obj = obj.offsetParent )!=null) {
offsetTop += obj.offsetTop;
offsetLeft += obj.offsetLeft;
}
return [offsetLeft, offsetTop];
}

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.