Salut à tous, voici mon problème du jour.

J'ai deux listes identiques pour mes tests. La seule différence est que l'une est dimensionnée en CSS de façon à avoir un ascenseur vertical. Au survol d'un élément de la première liste, l'ascenseur descend jusqu'à sont élément jumeau de la seconde liste. Le script que j'ai développé fonctionne sous FF3, IE7 et Safari 3. Malheureusement, il a un comportement étrange sous Opera 9(.62).

Voici le code (directement exécutable) à tester, désolé je n'ai pas pu faire plus simple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   <title></title>
   <style type="text/css">
   * {margin:0;padding:0;color:#fff;}
   body {background:#000;}
   #liste {width:100px;background:#333;}
   #listeOverflow {width:100px;height:150px;overflow:auto;background:#666;}
   a {background:#999;}
   </style>
</head>
<body>
   <ul id="liste"></ul>
   <ul id="listeOverflow"></ul>
   <script type="text/javascript">
   var o = function() {
      this.b = { "bla": { "p1": "va1", "p2": "va2" },
         "ble": { "p1": "ve1", "p2": "ve2" },
         "bli": { "p1": "vi1", "p2": "vi2" },
         "blo": { "p1": "vo1", "p2": "vo2" },
         "blb": { "p1": "vu1", "p2": "vu2" },
         "blc": { "p1": "va1", "p2": "va2" },
         "bld": { "p1": "ve1", "p2": "ve2" },
         "blf": { "p1": "vi1", "p2": "vi2" },
         "blg": { "p1": "vo1", "p2": "vo2" },
         "blh": { "p1": "vu1", "p2": "vu2" },
         "blj": { "p1": "va1", "p2": "va2" },
         "blk": { "p1": "ve1", "p2": "ve2" },
         "bll": { "p1": "vi1", "p2": "vi2" },
         "blm": { "p1": "vo1", "p2": "vo2" },
         "bln": { "p1": "vu1", "p2": "vu2" },
         "blp": { "p1": "va1", "p2": "va2" },
         "blq": { "p1": "ve1", "p2": "ve2" },
         "blr": { "p1": "vi1", "p2": "vi2" },
         "bls": { "p1": "vo1", "p2": "vo2" },
         "blt": { "p1": "vu1", "p2": "vu2" }
      };
      var offset = 0;
 
      this.afficherListe = function() {
         var me = this;
 
         for (var i in me.b) {
            if (typeof (me.b[i]) == "object") {
               var ref = document.createTextNode(i);
               var a = document.createElement("a");
               var li = document.createElement("li");
 
               var refJumeau = document.createTextNode(i);
               var aJumeau = document.createElement("a");
               var liJumeau = document.createElement("li");
 
               a.href = "";
               aJumeau.href = "";
               a.appendChild(ref);
               li.appendChild(a);
               aJumeau.appendChild(refJumeau);
               liJumeau.appendChild(aJumeau);
               document.getElementById("liste").appendChild(li);
               document.getElementById("listeOverflow").appendChild(lio);
               a.a = aJumeau;     // ligne 63
               a.onmouseover = function() {
                  glisserAscenseur(this.Jumeau, me);     // ligne 65
                  return false;
               }
            }
         }
      }
 
      function obtenirPosition(o) {    // merci le_chomeur
        // position x / y de l'objet
        var x = o.offsetLeft || 0;
        var y = o.offsetTop || 0;
        var coords = [];
        // tant qu'il y a un parent, on ajoute la position de son parent
        while (o = o.offsetParent) {
            x += o.offsetLeft;
            y += o.offsetTop;
        }
        coords.X = x;
        coords.Y = y;
        return coords;
      }
      function glisserAscenseur(a, me) {
         var conteneur = document.getElementById("listeOverflow");
         var positionDuConteneur = obtenirPosition(conteneur);
         var positionDuContenu = obtenirPosition(a);
         var yEnCoursDuContenu = positionDuContenu.Y - offset;
         var direction = "";
 
         if (positionDuConteneur.Y<yEnCoursDuContenu) {
            direction = "bas";
         } else if (positionDuConteneur.Y>yEnCoursDuContenu) {
            direction = "haut";
         }
 
         alert(positionDuContenu.Y +' - '+ offset +' = '+ yEnCoursDuContenu +' ('+ direction +')');     // ligne 99
         if (direction!="") {
            i = setInterval(function() {
               yEnCoursDuContenu = glisserAscenseurParPas(conteneur, positionDuConteneur.Y, yEnCoursDuContenu, direction, me);
            }, 5);
         }
      }
      function glisserAscenseurParPas(conteneur, positionDuConteneurY, positionDuContenuY, direction, me) {
         var pas = 10;
         if (Math.abs(positionDuConteneurY - positionDuContenuY)<10) pas = 1;
         if (direction=="bas") {
            conteneur.scrollTop += pas;
            positionDuContenuY -= pas;
         } else {
            conteneur.scrollTop -= pas;
            positionDuContenuY += pas;
         }
 
         if (positionDuConteneurY==positionDuContenuY) {
            offset = conteneur.scrollTop;
            clearInterval(i);
         }
         return positionDuContenuY;
      }
   }
 
   var t = new o();
   t.afficherListe();
   </script>
</body>
</html>
Pour le tester il suffit de survoler les liens un à un en descendant à partir de blb, par exemple. Normalement la liste jumelle descend aussi, sous Opera la liste jumelle monte et descend. On peut aussi survoler le même lien, il ne devrait rien se passer, pourtant sous Opera ça monte et ça descend.

Une alerte se trouve à la ligne 99, elle montre que positionDuContenu.Y est incohérent sous Opera. Cette valeur est obtenue via le calcul de position posté par le_chomeur. Je n'ai rien trouvé concernant un problème de position sous Opera, je pense donc que le problème vient de l'argument que je lui passe et qui trouve son origine à la ligne 65 du code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
a.onmouseover = function() {
   glisserAscenseur(this.aJumeau, me);
   return false;
}
.
Voilà où j'en suis et où je bloque depuis vendredi. Sauriez-vous d'où cela peut venir? Peut-on faire ce que je fais à la ligne 63 par exemple?