Il était une fois un gentil garçon admin sys/webmaster à ses heures perdues qui, pour aider une amie, a fait le nécessaire pour qu’elle vienne faire son stage de webmistress dans son bureau.
Soit. Cadeau un peu empoisonné (je pensais qu’elle allait m’apporter une compétence, au final je lui ai quasi tout appris), mais cadeau quand même. Bref, cette amie veut se monter un portfolio, avec un ptit menu dynamique en CSS tout bete (genre clic sur un lien, pouf un menu qui s’affiche). Le problème, c’est que l’emplacement du menu est pas connu à l’avance, surtout si on gère les résolutions multiples ET les navigateurs différents.
du coup y’a fallu que je creuse mes méninges, le msdn (je savais pas qu’ils avaient une rubrique dev html/css, super bien foutue d’ailleurs), les forums, la rubrique webdev de mozilla… et les references CSS, bien minces.
Alors que tout était perdu ou presque, j’ai fait la découverte de la propriété « offsetLeft/Top/Width/Height », qui renvoie le positionnement par rapport au conteneur.
Tout était beau et rose dans mon petit monde, jusqu’à ce qu’on teste le site sous IE. Et là, c’est le drame. vivi ma ptite dame,le drame. rien ne se positionnait plus. Jusqu’à ce que je fouillasse une fois de plus le ouaibe à la recherche de LA réponse, que jamais je ne trouva. (chuis pas sûr de passer au maitre cappelo validator sur cette phrase là). Du coup, je l’ai inventée (oué enfin bon me suis pas non plus über pété le fion, mais si j’avais pas résolu ce problème ce soir j’aurais pas réussi à dormir).
En fait le truc est le suivant :
gecko renvoie dans offsetTop/Left le positionnement par rapport au conteneur « body ».
ie renvoie, lui, le positionnement par rapport au conteneur parent. Du coup forcément ça chiait dans la colle.
bref, le moment tant attendu, le code
[code]/* element renvoyé par document.getElementById(name), attr = « offsetTop » ou « offsetLeft » /
function calculeOffset(element,attr){
if (document.all) {
offset = element[attr];
while (element.offsetParent) {
offset += element.offsetParent[attr];
element = element.offsetParent;
}
} else {
offset = element[attr];
}
return offset
}
/ et en bonus la fonction qui affiche le menu, qui prend en parametre l’id du menu (contenu dans une balise div), et l’id du lien (pour le postionnement) */
function affiche(menu,source) {
bloc = document.getElementById(menu);
bsource = document.getElementById(source);
pos_x = calculeOffset(bsource, « offsetLeft »);
pos_y = calculeOffset(bsource, « offsetTop »);
off_x = bsource[« offsetWidth »];
off_y = bsource[« offsetHeight »];
pos_x = pos_x + off_x +« px »;
pos_y = pos_y + off_y +« px »;
bloc.style.left = pos_x;
bloc.style.top = pos_y;
if (bloc.style.visibility == "hidden") {
bloc.style.display = "block";
bloc.style.visibility = "visible";
} else {
bloc.style.visibility = "hidden";
bloc.style.display = "none";
}
}[/code]
chose étonnante (j’ai pas creusé, il est 00:27 et je bosse demain à 8h, je verrais plus tard), il est apparemment nécessaire de mettre style="visibility: hidden; display: none;"
dans la balise div du menu, sinon il faut cliquer 2 fois pour le faire apparaitre… je suppose que block.style.visibility est vide quand on met la visibility sur hidden dans la CSS, si c’est le cas je modifierai le test pour le cas "visibility == « » ".
Merci de m’avoir lu, en esperant que ça puisse servir à d’autres
(en tout cas j’aurais été super content de trouver ce genre d’infos plus tot, ça m’aurait fait gagner au moins 1h de sommeil ou de lecture :P)