Page 1 sur 1

Gestion de calques visibles/invisibles en JS

Posté : 04 avr. 2005, 23:58
par albat
Bonjour à tous,

Une question un peu costaud mais, je le crois, intéressante...

J'ai une page qui peut se diviser en 3 parties (de haut en bas) :
- entête
- partie centrale
- pied

La partie entête contient 4 liens destinés à commander l'affichage alternatif de <div> que j'ai baptisés "volets".
La partie centrale est l'emplacement où doit s'afficher le volet activé (les 3 autres étant alors désactivés = invisibles).
Le pied de page s'affiche tout en bas. Vous voyez, c'est tout simple.

Règles de fonctionnement :
- Un seul volet peut s'afficher à la fois (1 activé => 3 désactivés).
- Les volets s'affichent tous au même emplacement (à tour de rôle) => top:0px et left:0px
- Les volets sont de hauteur variable (non connue).
- Le pied de page doit s'afficher juste au cul du volet affiché au-dessus, quellle que soit sa hauteur.

Actuellement (avec le code ci-dessous) :
- tous les onglets sont affichés, superposés les uns sur les autres.
- l'appel de la fonction afficheVolet() ne marche pas (j'ai essayé plusieurs syntaxes, sans grand succès)
- le pied de page vient se coller au bas de l'entête et les 4 volets, tous affichés, se superposent sur le pied (et donc sortent du cadre de la page. Bâââh...)

.conteneurAlternatif
  { position:absolute;
    display:block;
    width:auto;
    margin-left:0px;    /* margin-left:auto; */
    margin-right:0px;   /* margin-right:auto; */
    margin-top:25px;
    margin-bottom:0px;
    top:0px;
    left:0px;
  }
<script type="text/javascript">
function afficheVolet(indice) // Affichage alterné des volets
{ for (i=1 ; i<5 ; i++)
      { var volet = document.getElementById('volet'+indice);
        volet.style.visibility = (i==indice ? "visible" : "hidden");
      }
}
</script>
// ...
       <a href='javascript:afficheVolet(1);'><div class='languetteOn' onClick='afficheVolet(1);return false;'>Volet1</div></a>
       <a href='javascript:afficheVolet(2);'><div class='languetteOn' onClick='afficheVolet(2);return false;'>Volet2</div></a>
       <a href='#'><div class='languetteOn' onClick='afficheVolet(3);return false;'>Volet3</div></a>
       <div class='languetteOn' onClick='afficheVolet(4);return false;'><a href='#'>Volet4</div></a>
// ...
       <table style="width:730px;padding:0px;">
       <tr><td>
               <div style="z-index:1;position:relative;top:0px;left:0px">
                   <div id="onglet1" class="conteneurAlternatif" style="z-index:1;border:1px solid #00FF00;">
                       <p>Blablabla</p>
                   </div>
                   <div id="onglet2" class="conteneurAlternatif" style="z-index:1;border:1px solid #0000FF;">
                       <p>Blebleble</p>
                   </div>
                   <div id="onglet3" class="conteneurAlternatif" style="z-index:1;border:1px solid #FF8000;">
                       <p>Bliblibli</p>
                   </div>
                   <div id="onglet4" class="conteneurAlternatif" style="z-index:1;border:1px solid #FF0000;">
                       <p>Blobloblo</p>
                   </div>
               </div>
           </td></tr>
       </table>
// ...
À force de tripatouiller mon code dans tous les sens, je commence à ne plus y voir très clair.
Aussi, j'en appelle à votre regard tout neuf et à vos neurones certainement beaucoup plus frais... :lol:

D'avance, big merci ! :agenouille:

Posté : 05 avr. 2005, 11:32
par flitox
Bon albat je tente quelquechose :lol:

Code : Tout sélectionner

var volet = document.getElementById('volet'+indice);
Tu cherches à afficher volet1, volet2, volet3, volet4 et dans tes div ils portent le nom onglet1, onglet2, onglet3, onglet4

C'est louche ?

Et puis si c'est pas ça ça ne fera que confirmer ce que je t'ai dis dans le message privé :D

Posté : 05 avr. 2005, 11:42
par albat
C'est louche ?
Non. C'est faux. :lol:
L'alcool est un fléau...

C'est corrigé ("onglet" renommés en "volet") mais ça suffit pas.

Posté : 05 avr. 2005, 11:51
par flitox

Code : Tout sélectionner

i==indice
Lui il est louche je le sens bien :lol:

Si c'est encore pas bon (quoique tu as fais une petite correction suite à ma première réponse :langue: ) je retourne glander...

Cherche entreprise où on bosse. Urgent!

Posté : 05 avr. 2005, 12:04
par albat

Code : Tout sélectionner

i==indice
Lui il est louche je le sens bien :lol:
Non, ce n'est pas lui qui pose problème.
Le remplacement des "onglet" par "volet" a bien sûr été grandement bénéfique (j'en rougis encore de honte) mais il n'a pas tout rétabli.
Cherche entreprise où on bosse. Urgent!
Cherche entreprise qui paie. Même sans rien foutre.

Posté : 05 avr. 2005, 13:01
par sadeq
L'erreur est dans la boucle FOR de la fonction.

for (i=1 ; i<5 ; i++)
{ var volet = document.getElementById('volet'+indice);
volet.style.visibility = (i==indice ? "visible" : "hidden");
}

En effet, tu boucle par i pour exporer les DIV, tu dois alors faire un getElementById basé sur i et non sur indice

le bon code est :
for (i=1 ; i<5 ; i++)
{ var volet = document.getElementById('volet'+i);
volet.style.visibility = (i==indice ? "visible" : "hidden");
}

Et bien sure, en modifiant volet par onglet ou onglet par volet

Pour ce qui est du pied, il suffit d'ajouter un dernier <TR> avant </table>
pour y placer le div du pied. sans calculer son emplacement par rapport aux calques alternatifs.

Posté : 05 avr. 2005, 14:48
par albat
L'erreur est dans la boucle FOR de la fonction.
En effet, tu boucle par i pour exporer les DIV, tu dois alors faire un getElementById basé sur i et non sur indice
=D> =D> =D> Mais bien sûr !
C'était tout bête, mais je n'y voyais vraiment plus clair.
Merci ! Merci ! Merci !

Il ne me reste plus qu'à régler le problème de calage pour éviter que mes volets s'affichent en superpo avec le pied...
Pour ce qui est du pied, il suffit d'ajouter un dernier <TR> avant </table>
pour y placer le div du pied. sans calculer son emplacement par rapport aux calques alternatifs.
... et là, ça me pose un peu problème parce que ça me fout en l'air toutes mes imbrications...
Bon, je me plonge dedans et je fais signe dès que je remonte à la surface !
Encore merci ! :wink:

Re: Gestion de calques visibles/invisibles en JS

Posté : 06 avr. 2005, 01:59
par albat
Il ne me reste à présent qu'un des deux problèmes que j'avais indiqués.
Encore merci à Sadeq et Flitox !

Le problème restant est le suivant :
- mes 4 volets s'affichent bien à tour de rôle quand ils sont appelés
- ils s'affichent juste en-dessous de la section précédente (LANGUETTES)
mais
- le pied se superpose avec le volet affiché au lieu de se placer juste en-dessous :sad:
(dit autrement : les sections VOLETS et PIED s'affichent toutes deux au cul de la section LANGUETTES, au lieu de se succèder.)
<div ...>
    <div ...>
// ...
// SECTION LANGUETTES
       <a href='javascript:afficheVolet(1);'><div class='languetteOn' onClick='afficheVolet(1);return false;'>Volet1</div></a>
       <a href='javascript:afficheVolet(2);'><div class='languetteOn' onClick='afficheVolet(2);return false;'>Volet2</div></a>
       <a href='javascript:afficheVolet(3);'><div class='languetteOn' onClick='afficheVolet(3);return false;'>Volet3</div></a>
       <a href='javascript:afficheVolet(4);'><div class='languetteOn' onClick='afficheVolet(4);return false;'>Volet4</div></a>
// ...
// SECTION VOLETS
       <table style="width:730px;padding:0px;">
       <tr><td>
               <div style="z-index:1;position:relative;top:0px;left:0px">
                   <div id="volet1" class="conteneurAlternatif" style="z-index:1;border:1px solid #00FF00;"><p>Blablabla</p></div>
                   <div id="volet2" class="conteneurAlternatif" style="z-index:1;border:1px solid #0000FF;"><p>Blebleble</p></div>
                   <div id="volet3" class="conteneurAlternatif" style="z-index:1;border:1px solid #FF8000;"><p>Bliblibli</p></div>
                   <div id="volet4" class="conteneurAlternatif" style="z-index:1;border:1px solid #FF0000;"><p>Blobloblo</p></div>
               </div>
           </td></tr>
       </table>
    </div>
</div>
// SECTION PIED
<?php
include("footer.php");
?>
// ...
Je ne peux donc pas inclure le pied de page (défini par le fichier footer.php) dans le <table> comme le conseillait Sadeq.
En tout cas, je ne vois pas comment... :-k

J'ai fait plusieurs essais.
Tout ce que j'ai réussi à faire, c'est foutre en l'air mon affichage ! :x

Quelqu'un d'un peu plus doué que moi ?... [-o<

Posté : 06 avr. 2005, 16:47
par sadeq
Désolé pour le coup du pied dans le <TR>, en fait ça va pas marcher puisque les div's sont en position absolue par rapport à la table.

Le pied dans ce cas doit être dans un DIV à position absolue dont le top est calculé selon le top et la hauteur du dernier calque affiché.

Pratique:
Supposant que dans le pied se trouve dans un div nommé "PIED", il faut modifier ton script JS pour l'afficher juste après le calque activé :
for (i=1 ; i<5 ; i++) { 
   var volet = document.getElementById('volet'+i); 
   volet.style.visibility = (i==indice ? "visible" : "hidden"); 
   if (volet.style.visibility=="visible")  document.getElementById('PIED').style.top = volet.style.top + volet.style.height;
}

Posté : 06 avr. 2005, 17:14
par albat
Ton astuce est bonne, mais en aucun cas je ne peux déterminer la valeur de volet.style.height.
L'un de ces volets, par exemple, contient des résumés de livres et leur taille est variable.
Je ne peux donc jamais fixer la hauteur d'un quelqconque de ces volets. :(

L'idéal serait de pouvoir écrire un truc dans le genre de :
  if (volet.style.visibility=="visible")  document.getElementById('PIED').style.top = volet.style.bottom; 
Au fait, c'est possible ?... :-k

PGM ReCogiTé

Posté : 07 avr. 2005, 14:20
par sadeq
J'ai repensé ton programme et arrivé à cette solution simple:
Au lieu d'agir sur la visibilité et le positionnement des voles, il vaut mieux
transferer leur contenu dans un afficheur à position stable.

Je m'explique:

t'as un menu, une surface prévue pour tes calques altenatifs et un pied.
La position des div's doit être stable et non absolue.

L'idée est de prévoir un div vide appelé "AFFICHEUR" et des div's invisibles contenant les données des calques.

La mission de JS est d'affecter dans le div AFFICHEUR le contenu HTML du volet (div) sélectionné dans le menu .

Le code devient comme suit :
Code:

Code : Tout sélectionner

<style> .conteneurAlternatif { display:block; width:auto; margin-left:0px; margin-right:0px; margin-top:25px; margin-bottom:0px; visibility:hidden } </style> <script type="text/javascript"> function afficheVolet(indice) { // Affichage alterné des volets for (i=1 ; i<5 ; i++) { var volet = document.getElementById('volet'+i); //Afficher le contenu du div source correspondant à l'indice sélectionné if (i==indice) document.getElementById("AFFICHEUR").innerHTML=volet.innerHTML; } } </script> <a href='javascript:afficheVolet(1);'><div class='languetteOn' >Volet1</div></a> <a href='javascript:afficheVolet(2);'><div class='languetteOn' >Volet2</div></a> <a href='javascript:afficheVolet(3);'><div class='languetteOn' >Volet3</div></a> <a href='javascript:afficheVolet(4);'><div class='languetteOn' >Volet4</div></a> <div id=AFFICHEUR> </div> <div id=PIED> <p>Je suis le Pied</p> </div> <div id="volet1" class="conteneurAlternatif" > <p>Blablabla</p> </div> <div id="volet2" class="conteneurAlternatif" > <p>Blebleble</p> </div> <div id="volet3" class="conteneurAlternatif" > <p>Bliblibli</p> </div> <div id="volet4" class="conteneurAlternatif" > <p>Blobloblo</p> </div>

Posté : 07 avr. 2005, 23:43
par albat
Très astucieux comme procédé, cela permet d'aborder le problème par un autre biais.

Je n'ai malheureusement pas le temps de le tester maintenant.
Je pars demain à l'aube et reviens lundi après-midi.
Mais je te promets que je reviendrai te dire ce que cela donne.

Encore mille mercis et bravo pour ton idée ! ;)

Posté : 29 avr. 2005, 18:20
par albat
Eurékâ !
J'ai trouvé la solution grâce à un bout de code présenté par dark_vidor
(que je remercie très sincèrement) sur un autre sujet de ce forum. :D
http://www.phpfrance.com/forums/voir_sujet-2396.php

L'astuce était de jouer sur la propriété display et non visibility.
Quand on le sait, ça paraît logique, voire évident, mais je n'aurais jamais trouvé seul.

Grand merci aussi à Sadeq pour son aide plus que précieuse
et dont je vais tester avec attention la proposition de code ! =D>
Ça peut apporter d'autres idées...

Posté : 29 avr. 2005, 18:37
par Cyrano
Bien vu pour le display, j'allais suggérer une autre solution (peut-être moins élégante?) : fixer la hauteur de tes div toutes semblables avec une propriété CSS overflow: auto: de cette manière, le pied de page peut même être en position absolue juste en dessous sans être chevauché, et si le contenu dépasse, il y a une barre de défilement disponible.

Posté : 29 avr. 2005, 18:42
par albat
Tout à fait, mais puriste comme je le suis, je ne voulais pas fixer la hauteur de mes div. ;)
Leur contenu est dynamique et je souhaitais un affichage adaptable.

J'espère pouvoir te montrer pourquoi avant le 12 mai, date que je me suis fixé pour la mise en ligne... ;)