Obtenir l' offset par rapport au premier parent positionné

0/5 (3 avis)

Snippet vu 8 008 fois - Téléchargée 19 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
XtremDuke Messages postés 626 Date d'inscription samedi 28 septembre 2002 Statut Membre Dernière intervention 18 mai 2009 4
7 août 2007 à 09:20
hô ! bon désolé ^^
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 4
6 août 2007 à 23:19
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É***.
XtremDuke Messages postés 626 Date d'inscription samedi 28 septembre 2002 Statut Membre Dernière intervention 18 mai 2009 4
6 août 2007 à 11:41
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.