11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

J'ai une arborescence comme on peut la voir sur les systèmes d'exploitation (mode grahique bien sûr Smiley ravi ).

Voici un exemple :

<p class="dossier">Dossier racine</p>
      <p class="dossier" style="margin-left:20px">Dossier A</p>
                <p class="dossier" style="margin-left:40px">Dossier AA</p>
                <p class="dossier" style="margin-left:40px">Dossier AB</p>
                       <div class="relative" onMouseOut="masquer('infoFichier3');">
                                <p class="jpg"  style="margin-left:60px"><a class="boite" href="..." title="" onMouseOver="affiche('infoFichier');" >Fichier 1 dans AB</a></p>
                      </div>
      <p class="dossier" style="margin-left:20px">Dossier B</p>

     etc...


Explications :
- lorsqu'il s'agit d'un dossier, j'utilise un élément <p> avec la classe dossier qui prévoit une image de fond. Pour donner un effet "arborescence", j'utilise un padding qui est calculé selon le niveau du dossier (info tirée de la base de données)
- lorsqu'il s'agit d'un fichier, j'utilise un élément <div> qui contient un élément <p> qui encadre le nom et le lien du fichier. J'utilise cet élément (<div>) car il a des éléments que je dois afficher mais que je n'ai pas jugé utile de mettre dans la portion de code. (cela pour justifier l'emploi du <div> Smiley cligne )

Je voudrais savoir comment je peux faire pour qu'au clic d'un dossier son contenu direct soit affiché, c'est-à-dire ce qu'il contient mais pas ses sous sous dossiers et fichiers.
Du même coup, il faut que si le contenu d'un autre dossier était affiché, il soit masqué.

Je ne vois pas du tout comment faire et mes connaissances en javascript et DOM sont légères.

Merci de votre aide.
Je peux te proposer mon propre script que j'ai mis sur mon site.
Ici : lien vers l'article

Il faudra adapter bien sûr, mais je pense que tu dois pouvoir en faire quelque chose. Testé avec IE6, mais il n'y a vraiment aucune raison, à mon avis, qu'il ne fonctionne pas ailleurs, étant donné que l'implémentation DOM d'IE est parmi les plus défectueuses...

Je te conseille par ailleurs de passer à une structure de liste imbriquées comme proposé dans mon script. Tu as trois alternatives : UL, OL et DL, UL est à mon avis de loin la plus adéquate.
Pour moi, ta structure en P et DIV est une mauvaise séparation contenu/présentation, car la structure arborescente doit apparaître dans le code HTML et non uniquement grâce à des effets CSS.
Essaie de désactiver les CSS... je suis quasiment sûr que l'arborescence devient difficilement repérable.
Pour un lecteur d'écran, elle en devient presque totalement impossible.

EDIT : Veuillez m'excuser pour la longueur de lien un peu longue mais le forum n'a pas voulu de mon lien encadré des habituels [ url=...]...[ /url]. Dew si tu passes par là, peux-tu contrôler tes regexp? Merci. J'ai l'impression que c'est l'apostrophe qui fait planter.

EDIT par Felipe: sans l'apostrophe ton lien fonctionne encore. Du moment qu'il y a script61- au début Smiley cligne
Modifié par Felipe (15 Aug 2007 - 02:17)
je n'ai pas encore regardé ton script mais j'ai utilisé une structure en P et DIV car au survol d'un fichier, j'ai le bloc DIV qui s'affiche. Il contient un résumé et surtout un formulaire. Or, je ne sais pas si je peux mettre un FORM dans une LI.

Alors je pose la question : peux ton mettre la balise FORM dans une LI ?

En tout cas merci, dès que possible je te donne des nouvelles.

EDIT: je viens de tester, c'est super comme script, mais le pb c'est que ie bloque le contenu actif au chargement de la page et ça c'est assez pénible. Une solution ?
Modifié par Felipe (15 Aug 2007 - 02:18)
Modérateur
Salut,

sylvainbucule a écrit :
Alors je pose la question : peux ton mettre la balise FORM dans une LI ?
oui, pas de problème.

a écrit :
je viens de tester, c'est super comme script, mais le pb c'est que ie bloque le contenu actif au chargement de la page et ça c'est assez pénible. Une solution ?
Sans doute parce que tu l'as testé en local... En ligne, ça ne doit pas bloquer. Smiley cligne
Felipe a écrit :
EDIT par Felipe: sans l'apostrophe ton lien fonctionne encore. Du moment qu'il y a script61- au début.

J'ai pas pensé à celle-là. Bien vu.

a écrit :
[quote=sylvainbucule]Alors je pose la question : peux ton mettre la balise FORM dans une LI ?
oui, pas de problème.
Tu peux même garder tes div à l'intérieur des li, c'est toujours valide normalement. L'élément LI a ceci de particulier qu'il peut accepter quasiment n'importe quelle balise bloc ou en ligne.

a écrit :
[quote=sylvainbucule]je viens de tester, c'est super comme script, mais le pb c'est que ie bloque le contenu actif au chargement de la page et ça c'est assez pénible. Une solution
?

Sans doute parce que tu l'as testé en local... En ligne, ça ne doit pas bloquer.
+1. Encore cette stupidité de restriction d'IE.
J'utilise WAMP en local sur 127.0.0.1, je n'ai jamais ce problème. C'est vraiment quand tu utilises le protocole file://
Tu as dû par inadvertance ouvrir le fichier HTML par entrée ou par double-clic... c'est l'erreur à ne pas faire.
Il faut impérativement ouvrir le navigateur, et ensuite taper l'adresse en utilisant 127.0.0.1 ou localhost au lieu de file://
re-bonjour,

me revoilà avec mon arborescence. Je n'avais pas marqué résolu car je me doutais que j'allais revenir Smiley langue

J'ai utilisé le script de quentinC (merci à toi) et ça fonctionne nickel. Mais cette nouvelle structure arborescente faite de balises UL LI UL imbriquées pose un problème :

Avant de l'expliquer, voici le code correspondant, ça permettra peut être de mieux me faire comprendre Smiley langue


<ul>
      <li onclick="recupNom('dossierRacine')">dossier racine
            <ul>
                   <li onclick="recupNom('dossier1')">dossier1
                           <ul>
                              <li onclick="recupNom('dossier1.1')">dossier1.1</li>                  
                           </ul>
                   </li>
           </ul>
     </li>
</ul>



Explication du problème
- Si je clique sur le dossier racine, pas de problème, je récupère son nom.
- Si je clique sur le dossier1, la fonction se lance une première fois pour récupérer le nom "dossier1" puis une seconde fois pour récupérer le nom "dossier racine".
- Si je clique sur le dossier 1.1, la fonction se lance une première fois pour récupérer le nom "dossier1.1" puis une seconde fois pour récupérer le nom "dossier1" puis le nom "dossier racine".

Cela vient du fait (à mon avis) que les éléments sont imbriqués les uns dans les autres. Comment faire alors que la fonction ne se lance que pour le premier élément, à savoir si je clique sur le dossier1.1, je récupère que le nom 1.1 et pas les noms des dossiers parents.

Merci de votre aide. Smiley smile
Modifié par sylvainbucule (18 Aug 2007 - 17:11)
bon ben je peux pas dire que j'ai pas cherché!

Le problème c'est que la fonction est appelé pour chaque nouvel élément et je ne peux pas garder de variable javascript en mémoire pour réutiliser le résultat après.

Un peu d'aide serait la bienvenue Smiley sweatdrop
Modérateur
Salut,

Tiens, lis donc ce tuto . Ca va t'aider à voir quelles sont tes erreurs... Le premier chapitre "Ne misez pas tout sur Javascript" t'intéresse tout particulièrement. Smiley cligne
Modifié par koala64 (18 Aug 2007 - 22:44)
effectivement l'article est très interessant

Cependant ma page reste accessible si javascript est désactivé. Mais une fonctionnalité ne fonctionne pas qui intéresse l'administrateur du site, c'est à dire moi.

Après lecture, je sais que l'on peut détecter le clic de souris sans faire du javascript intrusif mais je ne sais pas le faire.

J'attends donc un coup de main sur mon problème tout en étant conscient de la maladresse. Je n'ai hélas pas le temps de me former convenablement (quoi que j'ai commandé un livre sur javascript que je ne devrais pas tarder à recevoir Smiley langue . Mais bon en attendant si on pouvait m'aider Smiley sweatdrop
Modérateur
ben dans le premier paragraphe, tu as un exemple avec le return false dont te parlait QuentinC. En fait, tu peux faire exactement ce qui est expliqué pour le lien d'impression (en l'adaptant à ton cas bien sûr). Smiley cligne
Modifié par koala64 (19 Aug 2007 - 00:25)
a écrit :
je sais que l'on peut détecter le clic de souris sans faire du javascript intrusif mais je ne sais pas le faire.


Le principe de base est simple : on remplace :
<tag id="xxxx" onclick="...">
par
document.getElementById('xxxx').onclick = function () { ... };

Mais dans le cas ici tu ne vas pas perdre ton temps à attribuer un id à chaque li, ni écrire une fonction spécifique à chaque fois. IL faut se servir des fonctions du DOM et faire des opérations un peu plus génériques.
Je te suggère de profiter des boucles déjà existantes dans mon script pour y ajouter les fonctions nécessaires, je pense que ça devrait te suffire sans avoir à parcourir les éléments avec une autre boucle. En plus tu gagnes du temps, puisque tu ne fais qu'un seul tour pour les deux fonctionnalités.
Bon et bien j'ai surfé pas mal de temps pour comprendre ton script QuentinC.Je l'ai donc commenté pour bien le comprendre, mais il y a quelques points sur la fin que je ne comprends pas. J'ai posé des questions au fur et à mesure de mes commentaires. Il n'y en a pas beaucoup.

Voici donc le code

//comment appeler cet élément ? C'est une variable qui contient deux fonctions ?
qcUlAutoTree =
{
    //je suppose que cela signigie, "prepareTrees est le nom de la fonction qui suit" ? ai-je tout juste ?
    "prepareTrees" : function ()
    {
    
      //j'affecte à la variable t l'objet balise <ul>
      var t = document.getElementsByTagName("ul");
    
      //pour tous les éléments <ul> trouvés, faire
      for (var i=0; i < t.length; i++)
      {
        
        //si l'élément <ul> à une classe qui a le nom navtree alors
        if (t[n].className.indexOf("navtree")!=-1)
        {
          //alors appeler la fonction createTree contenu dans la variable qcUlAutoTree avec en paramètre le numéro de la balise <ul> qui donne sa position dans la page
          qcUlAutoTree.createTree(t[n]);
        }
      }
    }
    , //je suppose que la virgule sert à séparer les deux fonctions qui sont affecter à la var qcUlAutoTree, non ?
    
    "createTree" : function  (ul)
    {
      // on affecte à la variable t l'élement qui a pour nom de balise <li>et qui est contenu dans la balise <ul> 
      var t = ul.getElementsByTagName("li");
      
      //pour tous les élément <li> trouvé dans <ul> faire
      for (var i=0; i < t.length; i++)
      {
        //à la variable li, on affecte l'objet <li> concerné par le tour de boucle
        var li = t[n]; //i en fait
        //à la variable h, on affecte l'objet <ul> enfant de <li> 
        var h = li.getElementsByTagName("ul");
        
        //s'il y a  au moins 1 élément ul enfant de li, alors
        if (h.length >0)
        {
          //dans le document, on crée un objet a que l'on affecte a la variable lnk
          var lnk = document.createElement("a");
          
          //on affecte l'attribut href avec le lien # à l'élément <a>créé
          lnk.setAttribute("href", "#");
          
          
          // au clic de l'élément <a> créé, appeler la fonction
          lnk.onclick = function ()
          {
            //récupérer le noeud parent de l'élément ul listé par la boucle
            //enfin là je ne comprends plus, qu'est-il fait exactement ?
            //que désigne this ? l'objet <a> ou l'objet <li> ?
            var o = this.parentNode.getElementsByTagName("ul")[0];
            
            //pour l'élément récupéré (lequel ?, je ne sais pas ce qu'est "o"), s'il n'est pas affiché, on lui affecte "-" s'il n'est pas affiché (je trouve pas cela logique !) sinon "+" s'il est affiché
            this.innerHTML = (o.style.display=="none"? "-" : "+");
            
            // pour l'élément contenu dans "o", s'il est affiché alors on le masque et vice versa
            o.style.display = (o.style.display == "none"? "block":"none");
            return false;
          };
          
          //on ajoute comme enfant à l'objet <a> un noeud de texte "+"
          lnk.appendChild(document.createTextNode("+"));
          
          //Insère dans l'élément <li> listé par la boucle un nœud enfant <a> avant le premier noeud enfant de l'élément li en question.
          li.insertBefore(lnk, li.firstChild);
          
          //masquer le contenu du premier élément <ul>
          h[0].style.display = "none";
        }
      }
    }
};


[#]Remarque : pour qu'il n'y ait pas de problème avec la balise italic, j'ai remplacé i par n lorsque c'était nécessaire

J'attends de vous quelques explications pour mes questions.

Je n'entrevois toujours pas la solution.
Modifié par sylvainbucule (19 Aug 2007 - 16:55)
Je réponds directement à la suite de tes questions, pour que ce soit plus simple. Si je n'ai rien mis, c'est que tu as compris correctement.


//comment appeler cet élément ? C'est une variable qui contient deux fonctions ?
//[b]Tout à fait. En programmation, on appelle communément ça un objet[/b]
qcUlAutoTree =
{
    //je suppose que cela signifie, "prepareTrees est le nom de la fonction qui suit" ? ai-je tout juste ?
//[b]Tout à fait. Je reconnais que la syntaxe utilisée ici est peu intuitive pour les débutants. C'est la syntaxe de déclaration d'un objet en JavaScript.[/b]
    "prepareTrees" : function ()
    {
    
      //j'affecte à la variable t l'objet balise <ul>
//[b]Pas exactement : je récupère un tableau de tous les éléments ul de la page.[/b]
      var t = document.getElementsByTagName("ul");
    
      //pour tous les éléments <ul> trouvés, faire
      for (var i=0; i < t.length; i++)
      {
        
        //si l'élément <ul> à une classe qui a le nom navtree alors
        if (t[n].className.indexOf("navtree")!=-1)
        {
          //alors appeler la fonction createTree contenu dans la variable qcUlAutoTree avec en paramètre le numéro de la balise <ul> qui donne sa position dans la page
//[b]Non, je passe directement l'objet ul concerné en paramètre.[/b]
          qcUlAutoTree.createTree(t[n]);
        }
      }
    }
    , //je suppose que la virgule sert à séparer les deux fonctions qui sont affecter à la var qcUlAutoTree, non ?
    //[b]Vien vu ![/b]

    "createTree" : function  (ul)
    {
      // on affecte à la variable t l'élement qui a pour nom de balise <li>et qui est contenu dans la balise <ul> 
//[b]Comme avant : je récupère un tableau contenant tous les <li> enfants du <ul>.[/b]
      var t = ul.getElementsByTagName("li");
      
      //pour tous les élément <li> trouvé dans <ul> faire
      for (var i=0; i < t.length; i++)
      {
        //à la variable li, on affecte l'objet <li> concerné par le tour de boucle
        var li = t[n]; //i en fait
        //à la variable h, on affecte l'objet <ul> enfant de <li> 
        var h = li.getElementsByTagName("ul");
        
        //s'il y a  au moins 1 élément ul enfant de li, alors
        if (h.length >0)
        {
          //dans le document, on crée un objet a que l'on affecte a la variable lnk
          var lnk = document.createElement("a");
          
          //on affecte l'attribut href avec le lien # à l'élément <a>créé
          lnk.setAttribute("href", "#");
          
          
          // au clic de l'élément <a> créé, appeler la fonction
          lnk.onclick = function ()
          {
            //récupérer le noeud parent de l'élément ul listé par la boucle
            //enfin là je ne comprends plus, qu'est-il fait exactement ?
            //que désigne this ? l'objet <a> ou l'objet <li> ?
//[b]Ici this représente le lien <a>[/b]
            var o = this.parentNode.getElementsByTagName("ul")[0];
            
            //pour l'élément récupéré (lequel ?, je ne sais pas ce qu'est "o"), s'il n'est pas affiché, on lui affecte "-" s'il n'est pas affiché (je trouve pas cela logique !) sinon "+" s'il est affiché
//[b]la variable o contient le ul enfant du li qui est parent du a... je ne sais pas si c'est clair, mais en d'autre termes il contient le ul qui représente le sous-arbre de l'élément cliqué[/b]
//[b]Pour les "+" et les "-", il ne faut pas oublier que ta logique est ici contraire, puisque j'inverse ensuite l'état affiché/non affiché de l'élément.[/b]
//[b]Il aurait été possible de mettre cette ligne après la suivante, et à ce moment-là il fallait inverser soit la condition, soit "+" et "-".[/b]            
this.innerHTML = (o.style.display=="none"? "-" : "+");
            
            // pour l'élément contenu dans "o", s'il est affiché alors on le masque et vice versa
            o.style.display = (o.style.display == "none"? "block":"none");
            return false;
          };
          
          //on ajoute comme enfant à l'objet <a> un noeud de texte "+"
          lnk.appendChild(document.createTextNode("+"));
          
          //Insère dans l'élément <li> listé par la boucle un nœud enfant <a> avant le premier noeud enfant de l'élément li en question.
          li.insertBefore(lnk, li.firstChild);
          
          //masquer le contenu du premier élément <ul>
          h[0].style.display = "none";
        }
      }
    }
};

Modifié par QuentinC (19 Aug 2007 - 23:58)
Bon et bien j'ai ce que je voulais. Merci beaucoup QuentinC pour ton script.

J'aurais aimé attribuer une classe à l'élément <a> créé pour ainsi pouvoir donner une plus grand taille au "+" et "-" de l'arborescence. Comment dois-je faire ?