OffsetTop - comportement hératique sur Firefox [Résolu]

Signaler
Messages postés
7
Date d'inscription
samedi 22 avril 2006
Statut
Membre
Dernière intervention
6 mai 2008
-
Messages postés
7
Date d'inscription
samedi 22 avril 2006
Statut
Membre
Dernière intervention
6 mai 2008
-
Bonjour,


Mon objectif: pouvoir positionner des images en superposition d'autres !


je me creuse la tête depuis pas mal de temps pour comprendre pourquoi
Firefox n'affiche pas correctement la page lors du premier chargement
de la page, mais par contre l'affiche correctement lorsque l'on la
réactualise !

Le problème revient si on vide le cache.

Cela marche bien avec Internet Explorer !


Il peut être constaté sur :
http://www.art-et-histoire.com/tempo.html

--> chargez la page --> le graphe n'est pas aligné avec le fond

--> actualisez --> les deux s'alignent

--> effacez votre cache --> nouveau désalignement

J'ai tenté de remplacer les document.write par du DOM pur, sur le conseil de SpaceFrog sur Developpez.com, mais cela ne change rien.

Voici mon code (simple):
<!-- BEGIN TEMPLATE: bbcode_code -->

Code :
<!--[if !IE]><--><!----><!--[endif]--><!--[if IE]>
<![endif]--><script language="Javascript" TYPE="text/javascript">
// position des réalisations,
function getOffsets(obj){
var offsetTop = obj.offsetTop;
var offsetLeft = obj.offsetLeft;
while((obj = obj.offsetParent)!=null){
offsetTop += obj.offsetTop;
offsetLeft += obj.offsetLeft;
}
return[offsetTop,offsetLeft];
}
</script>
"ly_carte2.jpg" style="border-width: 0px 0 0 0;">
 

"my_map">"reglyon.jpg" style="border-width: 0px 0 0 0">

<script language="Javascript" TYPE="text/javascript">
var obj1 =document.getElementById("my_map");
var top_map = getOffsets (obj1)[0];
var left_map = getOffsets (obj1)[1];
 
// position des réalisations, couleurs corrspondantes et image associée
document.write("
"position:absolute;top:"+top_map+"px;left:" + left_map +"px;">");
document.write(""reglyon.gif" WIDTH="662px" height="576px" border="0">");
document.write("
");
</script>

Laurent
Passionné d'art et d'histoire

16 réponses

Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
ravi que ça te convienne
l'important c'est que la page arrivera "toute faite",
    et à part le délai pour afficher, tout baignera.
<hr />                Cordialement            Bul        
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
Bonjour,

    pas très bien compris ce que tu  cherches à faire ?

    mais (obj1)[1]   ? c'est quoi ?

    comme tu fais juste deavnt var obj1 =document.getElementById("my_map");
       il n'y en a qu'1, et ce n'est pas un array !

<hr />                Cordialement            Bul        
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
ça doit d'ailleurs t'afficher une erreur...
¡————————¡——————————————————————————————————————————————————————————¡
|FireFox |regarder la "console d'erreurs" |
| | Outils / Console d'erreurs |
| | et mieux, télécharger FireBug |
¦————————¦——————————————————————————————————————————————————————————¦
|Internet|activer le deboggage : Outils/options Internet/Avancés |
|Explorer| dans la liste, sous "Navigation" : décocher |
| | ° Afficher une notification de chaque erreur de script |
| | ° Désactiver le débogage de Scripts (Internet Explorer) |
| | et mieux, télécharger le Debogger IE |
| | voir aussi DebugBar et Companion JS |
¦————————¦——————————————————————————————————————————————————————————¦
|K—Meleon|regarder la "console d'erreurs" |
| | Outils / Console d'erreurs |
¦————————¦——————————————————————————————————————————————————————————¦
|Opera |regarder la "console d'erreurs" |
| | utils / Asole d'erreurs |
¦————————¦——————————————————————————————————————————————————————————¦
|Safari |regarder Debug / Show JavaScript Console |
| |modif Fichier "Support:\Documents and Settings\utilisateur|
| |\Application Data\Apple Computer\Safari\Preferences.plist"|
| | y ajouter <key>IncludeDebugMenu</key> |
| | <true/> |
!————————!——————————————————————————————————————————————————————————!

et la taille / position des éléments : regarder ici par exemple ?
<hr />                Cordialement            Bul        
Messages postés
7
Date d'inscription
samedi 22 avril 2006
Statut
Membre
Dernière intervention
6 mai 2008

Merci pour la réponse spontanée



réponse à la première remarque (mon objectif):



Pour mieux comprendre clique sur ce lien.
Sur Firefox, tu devrais observer que le détail de la carte n'est pas aligné avec le fond (beige).
Mais si tu réactualise la page, ça marche !
Mon objectif --> que ça marche ds ts les cas ...
 
réponse à la deuxième remarque :
Ma fonction getOffsets(obj) retourne un array dont le premier élément est top et le deuxième est left.
Donc quand je récupère l'info, je fais : getOffsets (obj1)[0] pour avoir le "Top"

réponse à la troisième remarque :
la console d'erreur Mozilla ne relève aucune erreur, ni au chargement initial ni au rechargement.

Laurent
Passioné d'art et d'histoire
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
>>le détail de la carte n'est pas aligné
    ah...ok;
>>Mozilla ne relève aucune erreur

    bon uniquement un truc de positionnement , avec comportement

          IE et FF différent...

>>getOffsets(obj) retourne un array
    navré ! j'avais mal lu !  j'avais vu obj1[1]     
    houla... faut que j'aille au lit moi.

<hr />                Cordialement            Bul        
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
peux-tu essayer avec
 window.onload=function()
    {   var obj1 =document.getElementById("my_map");
         var top_map = getOffsets (obj1)[0];
         var left_map = getOffsets (obj1)[1];    ...

<hr />                Cordialement            Bul        
Messages postés
7
Date d'inscription
samedi 22 avril 2006
Statut
Membre
Dernière intervention
6 mai 2008

OK ça marche avec Windows.onload, mais l'exemple que j'ai soumis est ultra simplifié.
Sur mon site, j'ai pas loin d'un millier d'image à positionner (autant qu'il y a d'ouvrages sur une carte géographique)--> il faut que ça marche du premier coup.

Pour info voilà comment j'ai implementé la proposition avec windows.onload

<script language= "Javascript" TYPE="text/javascript">
// position de la première image,
var first_img    = document.createElement("img");
    with(first_img){
        id         = "my_map1"
        src        = "ly_carte2.jpg";
        style.borderWidth    = "0px 0 0 0";
    }
document.body.appendChild(first_img);
</script>
 

 
<script language="Javascript" TYPE="text/javascript">
// position de la seconde image,
var scd_img    = document.createElement("img");
    with(scd_img){
        src        = "reglyon.jpg";
        id         = "my_map"
        style.borderWidth    = "0px 0 0 0";
    }
document.body.appendChild(scd_img);

// prpéparation de l'image à superposer
var detail    = document.createElement("img");
 
    with(detail){
        src        = "reglyon.gif";
        id         = "my_detail"
        style.position    = "absolute";
         style.top        = "0px";
          style.left        = "0px";
        style.borderWidth    = "0px 0 0 0";
    }
 
document.body.appendChild(detail);

// on attend la fin de chargement du document, pour replaer l'image à superposer au bon endroit

function my_move()
    {
        var obj1 =document.getElementById("my_map"); // position de l'objet cible
        var top_map = getOffsets (obj1)[0];
        var left_map = getOffsets (obj1)[1];
        var obj2 =document.getElementById("my_detail"); // on récupère l'objet de l'image à superposer
        with(obj2){
             style.top        = top_map+"px";
              style.left        = left_map+"px";
        }
    }

window.onload=my_move;
</script>

Laurent
Passionné d'art et d'histoire
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
peu importe le nombre d'images   ;o)
FF déclenche parfois le javascript avant que le "html devant"
       ne soit interprété.   d'ou le onload.
il faut s'assurer que l'élément ( l'image)  est bien "actif"  avant
    d'y toucher.   on peut aussi tester complete sur l'image.
>>pas loin d'un millier d'image à positionner
    ça fait beaucoup... mais toutes sont dotées  d'actions ?
    et pourquoi n'avoir pas utilisé map + area simplement en html ?
<hr />                Cordialement            Bul        
Messages postés
7
Date d'inscription
samedi 22 avril 2006
Statut
Membre
Dernière intervention
6 mai 2008

En fait, pour chaque ouvrage à positionner sur la carte géographique, j'associe une couleur et une forme différente, ainsi qu'un lien actif permettant d'appeler la page correspondante.

voir la carte alsace-lorraine.

Là où ça se complique c'est que dans certains cas, je propose une carte de la région avec ses ponts, suivi une carte de la ville avec ses ponts. voir Paris :

Tout ça est généré en php, en dynamique à partir d'une base de données..
Avec une carte seulement ça marche, avec deux cartes, ça plante (au premier chargement), d'où mon appel à "expert".

Merci encore pour les conseils! je vais voir avec windows.onload, mais je crains que les temps de chargement ne soient rédhibitoires.

Passioné d'art et d'histoire
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
c'est très intéressant.

je ne sais pas si créer totalement cela en dynamique depuis une
    base de données  était une si bonne idée ?
sans critique aucune de quelques manières de quoi que ce soit !

ça me semble "simplement" relever de map + area en quasi pur htm

    ( ou ... généré en php )
<hr />                Cordialement            Bul        
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
ce que je voulais dire c'est plutot que de générer du javascript qui
    va positionner des choses avec appendChild et ce qui va avec
    tu pourrais générer du html du genre :

<MAP NAME='carte'>
Messages postés
7
Date d'inscription
samedi 22 avril 2006
Statut
Membre
Dernière intervention
6 mai 2008

J'y avais pensé, et je l'ai utilisé pour les cadres permettant de passer d'une région à l'autre.
Mais si mes connaissances sont exactes, avec MAP, on ne fait que désigner des zones actives "transparentes". Comment générer en surimpression mes ronds de couleurs et bordures différentes ? Je n'ai pas trouvé d'autres solutions que de créer autant d'IMG que d'ouvrages (en fait 4 src différents de IMG), et d'agir en Javascript sur la bordure et le background color.
Tt conseil est le bienvenu

Laurent
Passionné d'art et d'histoire
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
>>avec MAP, on ne fait que désigner des zones actives "transparentes".
    exact
    je pensais que tous les ponts ( rond et bordures ? ) pourraient être dans la carte.
    soit en dur
    soit insérés coté php ? php à tout ce qu'il faut pour le graphisme,
        le "temps" et le reste, seraient-il  meilleurs ?

<hr />                Cordialement            Bul        
Messages postés
13616
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
15 octobre 2013
34
ce ne sont peut-être que des idées, des pistes... stupides.
mais en affichant sans javascript : ça fonctionnerait toujours,
    bien entendu le temps d'affichage serait finalement le même, mais
    tout truc affiché sera cliquable au fûr et à mesure sans plantage.
<hr />                Cordialement            Bul        
Messages postés
7
Date d'inscription
samedi 22 avril 2006
Statut
Membre
Dernière intervention
6 mai 2008

Bravo !!!

Je n'avais jamis porté attention à la bibliothèque graphique désormais intégrée dans php qui permet de générer des images dynamiquement !!
Je m'y attèle, mais c'est une solution très séduisante, et manifestement très puissante.
Je viens de faire un bout d'essai, c'est pas compliqué à programmer.

Laurent
Passioné d'art et d'histoire
Messages postés
7
Date d'inscription
samedi 22 avril 2006
Statut
Membre
Dernière intervention
6 mai 2008

La technique reposant sur la bibliothèque graphique PHP est finalement extrèmement puissante.
Plutôt que de superposer les images côté client, j'ai pu le faire côté serveur, grâce à PHP, en générant au vol, l'image synthèse.
le résulat est observable sur mon site art-et-histoire.
Je peux transmettre le programme complet à ceux qu'ils le veulent.
http://www.art-et-histoire.com/index4q.php
Le seul souci est que cela génère un fichier temporaire, et oblige donc, d'une part de créer un fichier unique (de type image --> pas de fct PHP dispo - je l'ai bidouillée à partir de uniqid()), et de supprimer en fin de script ce fichier, en s'assurant qu'il est chargé côté client --> j'ai pas trouvé de solution automatique.

Quant à l'usage d'offsetTop, voici 4 recommandations importantes :

1/dérouler le script pour ts les éléments standards de la page

2/ créer ts les éléments flottants en position absolute 0

3/ par windows.onload les repositionner, en fonction de l'offset des premiers à partir de leur ID avec la fonction :
fonction qui récupère les coordonnées y,x (Top, Left) d'un objet

function
<script language="Javascript" TYPE="text/javascript">
//   
 getOffsets(obj) {
    var offsetTop1 = obj.offsetTop;
    var offsetLeft1 = obj.offsetLeft;
    while ((obj = obj.offsetParent )!=null) {
        offsetTop1 += obj.offsetTop;
        offsetLeft1 += obj.offsetLeft;
        }
    return [offsetTop1,offsetLeft1];
}
</script>
pour replacer l' (ou les) images à superposer au bon endroit
en mettant au fin du script :
<script language="Javascript" TYPE="text/javascript">
// on attend la fin de chargement du document, pour replacer l' (ou les) images à superposer au bon endroit
window.onload = function ()
    {
        if (eval(document.getElementById("my_map")))
        {
            var obj1 =document.getElementById("my_map"); // position de l'objet cible
            var top_map = getOffsets (obj1)[0];
            var left_map = getOffsets (obj1)[1];
            var obj2 =document.getElementById("my_detail"); // on récupère l'objet de l'image à superposer
            obj2.style.position        = 'absolute'; //impératif pour IE
            obj2.style.top        = top_map+"px";
            obj2.style.left        = left_map+"px";
           
        }
    }
</script>
4/ pour finir, ne pas oublier de reaffecter l'attribut "style.position" de l'objet flottant à "absolute", parce qu'IE l'aura oublié ....(petite bêtise qui m'a posé pas mal de souci, et dont la solution m'a été soufflée par sacha999 de developpez.com)

Laurent - Passionné d'art et d'histoire