[JS] Problem avec onclick

Problem avec onclick [JS] - HTML/CSS - Programmation

Marsh Posté le 28-09-2005 à 02:49:06    

Bonjour, quelqu'un pourrait m'expliquer pourquoi ca ca marche :
 


Butts[1].onclick = function()
    {
    for (LC = 0; LC < Divs[1].length; LC++)  
        {
        if(Divs[1][LC].style.display == 'block')
            {Divs[1][LC].style.display ='none';}
        else
            {Divs[1][LC].style.display ='block';}
        }
    return false;
    };
 
[etc....]
 
Butts[4].onclick = function()
    {
    for (LC = 0; LC < Divs[4].length; LC++)  
        {
        if(Divs[4][LC].style.display == 'block')
            {Divs[4][LC].style.display ='none';}
        else
            {Divs[4][LC].style.display ='block';}
        }
    return false;
    };
 


 
et pas ca :
 


 
for (LC2 = 1; LC2 < 5; LC2++)
{  
Butts[LC2].onclick = function()
    {
    for (LC = 0; LC < Divs[LC2].length; LC++)  
        {
        if(Divs[LC2][LC].style.display == 'block')
            {Divs[LC2][LC].style.display ='none';}
        else
            {Divs[LC2][LC].style.display ='block';}
        }
    return false;
    };
}
 


 
 
en gros, dans le cas qui marche j'énumère de 1 à 4 ce qui est remplacé par LC2 dans la boucle for qui marche pas.
 
C'est assez fort quand meme. La je pédale dans la choucroute. La seule expliquation que j'oserait avancer, c'est que onclick ne marche pas bien dans un boucle (pourquoi, j'en sais rien), mais j'en sait trop rien.
 
A savoir que ca ne me cause pas d'erreur, mais que ca ne fait rien (alors que ca devrait faire la meme chose que quand j'énumère a la main.


Message édité par Tentac le 28-09-2005 à 02:54:29

---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 02:49:06   

Reply

Marsh Posté le 28-09-2005 à 08:34:20    

normal, quand tu spécifie la function onclick sur l'élément
 
ben l'élément aura dans comme onclick :  

Code :
  1. Butts[LC2].onclick = function()
  2.     {
  3.     for (LC = 0; LC < Divs[LC2].length; LC++) 
  4.         {
  5.         if(Divs[LC2][LC].style.display == 'block')
  6.             {Divs[LC2][LC].style.display ='none';}
  7.         else
  8.             {Divs[LC2][LC].style.display ='block';}
  9.         }
  10.     return false;
  11.     };


 
 
et donc quand tu vas cliquer sur l'élément, tu peux me dire ce que vaudra LC2 ? ben nan tu sais pas justement, c'esdt pour ca que ca marche pas

Reply

Marsh Posté le 28-09-2005 à 15:24:43    

a pas sur de très bien comprendre. Ce que tu veux dire, c'est que quand je vais cliquer sur un des éléments, le onclick n'a pas moyen de savoir ou il en est dans le for, et donc ne peut pas connaitre LC2 ?
 
Donc en gros ca veut dire que c'est DMC pour créer dynamiquement une liste de boutons (Butts[LC2]) cliquable. Donc que je suis obligé de tout énumérer a la main, c'est ca ?


---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 15:28:08    

Faudrait que tu nous files tout le context de ton truc, genre la page HTML que tu as et le résultat que tu veux obtenir (un echantillon de 3 ou 4 boutons et DIV)
steuplééééééééééééééééééé

Reply

Marsh Posté le 28-09-2005 à 15:52:56    

pour les esquepliquations, c'est oversimple :
c'est dans mon système de news.
dans le tableau Butts[], il y a des divs qui ont chacun un ID différent, noté de 1 a n. (ce sont les boutons).
dans le tableau Divs[], il y a des listes de divs, dont la class est numéroté de 1 à n.  
 
ce que c'est censé faire (et ca marche si j'énumère), c'est que quand je clique sur le bouton qui a l'id 2, (par exemple), ca va m'afficher ou me cacher la liste de divs Divs[2][] .
 
Dans ma boucle, le premier LC2 sert donc a énumérer les boutons , et a agir sur la liste de divs en conséquence.  
Le LC sert ensuite a énumérer les divs de la liste en question (ben oui, j'ai plusieurs news de chaque classe).(cette partie marche bien).
 
je pourrait énumérer comme j'ai fait tout en haut pour le faire marcher, mais malheureusement, je connait pas le nombre de classe de news que je vais avoir a chaque fois, et je veux donc afficher que les boutons utiles (et accessibles, accessoiremement. les catégories accessibles dépendent du niveau de login).


Message édité par Tentac le 28-09-2005 à 15:53:24

---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 15:58:15    

l'application est la : http://www.choucroute-network.net/
va dans news, en haut tu as les boutons type 1 à 4 (c'est juste du texte). En les utilisant tu peux faire apparaitre/disparaitre les news correspondantes.
La c'est la version énumérée a la main, donc qui marche.
 
edit : ne pas faire gaffe aux alertes js, c'est pour moi (du débug).


Message édité par Tentac le 28-09-2005 à 15:59:28

---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 21:03:47    

Voici le joli code tant attendu,  
et la tu n'as même pas besoin d'énumérer les catégories à la main, elles sont automatiquement rajoutées.
J'utilise une méthode que le validateur W3C va pas forcément aimer, mais c'est valide si tu passes ta page en xHTML (mais en HTML ca marche pareil)
les catégories on l'attribut Cat, tout simplement
mais à la rigueur tu peux la remplacer par class.
ca fera l'affaire tout autant
 
avec l'exemple ici : http://gatsu.ftp.free.fr/html/showhideCat.html
 
mais il y a un truc que je pige pas dans la console de firefox j'ai ce message :  
 

Code :
  1. Erreur : [Exception... "'Error: No menu commaner found for URL: file:///D:/__css/pagetest.html' when calling method: [nsIDOMEventListener::handleEvent]"  nsresult: "0x8057001c (NS_ERROR_XPC_JS_THREW_JS_OBJECT)"  location: "<unknown>"  data: no]


Si quelqu'un pouvait m'éclairer ?
 
Bon voici le code. Normalement devrait pas y avoir d'erreur, il me semble très propre

Code :
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <head>
  4. <title></title>
  5.    <style>
  6.    #NewsFilter A {
  7.       margin: 0 5px;
  8.    }
  9.    </style>
  10.    <script>
  11.    function FilterNews() {
  12.       var NewsCats = new Array;
  13.       var NouvelleCat;
  14.       //On récuprèe d'abord les 2 gros blocs
  15.       var News = document.getElementById("News" );
  16.       var NewsFilter = document.getElementById("NewsFilter" );
  17.       //On va scanner le bloc de news afin de récupérer toutes les catégories de news différentes.
  18.       var TheNews = News.getElementsByTagName("DIV" ) //On recupère tous les DIV contenus dans News
  19.       //On va fouiller à la recherche des DIV qui contiennent une catégorie
  20.       for (var i=0; i<TheNews.length; i++) {
  21.          var Cat = TheNews[i].getAttribute("cat" )
  22.          NouvelleCat = true //On part du principe que chaque categorie rencontrée est nouvelle
  23.          if (Cat!="" ) { //Si le Div contient l'attribut cat
  24.             //On rajoute la catégorie dans un tableau
  25.             if (NewsCats.length>0) { //Si le tableau est vide la catégorie est systématiquement nouvelle
  26.                //On regarde si la categorie existe ou non
  27.                for (var j=0; j<NewsCats.length;j++) {
  28.                  if (NewsCats[j]==Cat) {
  29.                     NouvelleCat = false; //La categorie n'est pas nouvelle
  30.                     break; //On sort de la boucle
  31.                  }//end if
  32.                }//end for j
  33.             }//end if
  34.             if (NouvelleCat) { //Si la categorie est nouvelle
  35.                NewsCats.push(Cat); //On rajoute la nouvelle categorie
  36.             }//End if
  37.          }//End if
  38.       }//End for j
  39.      
  40.      //Maintenant nous avons un tableau de categories, il va falloir afficher ce tableau sous forme de lien ans le bloque NewsFilter
  41.    
  42.      NewsCats.sort() //On trie les categories par ordre alphabetique
  43.      //On va afficher les news dans le bloque maintenant
  44.      for (i=0; i<NewsCats.length; i++) {
  45.         var LienA = document.createElement("A" ); //On rajoute un lien A
  46.         LienA.href = "#";  //On lui rajoute un Href bidon afin qu'il soit bien considéré comme un A dans tous les navigateurs
  47.         var AValue = document.createTextNode(NewsCats[i]) //On créé le texte du A
  48.         LienA.appendChild(AValue) //On rajoute le text à A
  49.         LienA.onclick = function() { //On rajoute une fonction sur le onclick de ce A
  50.            //Cette fonction est autonome du code précédent, car elle sera appelée à chaque fois que on cliquera sur LienA
  51.            //Donc on doit refaire certaines actions
  52.             var News = document.getElementById("News" );
  53.             //On va fouiller à la recherche des DIV qui contiennent une catégorie
  54.             for (var i=0; i<TheNews.length; i++) {
  55.                var Cat = TheNews[i].getAttribute("cat" )
  56.                TheNews[i].style.display = (this.firstChild.nodeValue==Cat) ? "block" : "none"; //on cache ou on affiche un élément si celui ci correspond à la catégorie
  57.             } //end for
  58.             return false; //On empeche le lien de s'activer
  59.         } //end onclick
  60.         //On rajoute ce nouveau lien A dans le bloc
  61.          NewsFilter.appendChild(LienA);
  62.      } //end for
  63.    
  64.       //On rajoute un lien pour afficher toutes les news
  65.         var LienA = document.createElement("A" ); //On rajoute un lien A
  66.         LienA.href = "#";  //On lui rajoute un Href bidon afin qu'il soit bien considéré comme un A dans tous les navigateurs
  67.         var AValue = document.createTextNode("Toutes les news" ) //On créé le texte du A
  68.         LienA.appendChild(AValue); //On rajoute le text à A
  69.         LienA.onclick = function() { //On rajoute une fonction sur le onclick de ce A
  70.             var News = document.getElementById("News" );
  71.              for (var i=0; i<TheNews.length; i++) {
  72.                TheNews[i].style.display ="block";
  73.             } //end for
  74.             return false; //On empeche le lien de s'activer
  75.         } //end onclick
  76.         //On rajoute ce nouveau lien A dans le bloc
  77.          NewsFilter.appendChild(LienA);     
  78.    
  79.      
  80.    } //End function
  81.  
  82.    window.onload = function() {
  83.      FilterNews();
  84.    }
  85.    </script>
  86. </head>
  87. <body>
  88. <div id="NewsFilter"></div>
  89. <div id="News">
  90.    <div cat="News">
  91.    cat news
  92.    </div>
  93.    <div cat="Informatique">
  94.    cat info
  95.    </div>
  96.    <div cat="Fromage">
  97.    cat fromage
  98.    </div>
  99.    <div cat="Informatique">
  100.    cat info
  101.    </div>
  102.    <div cat="Politique">
  103.    cat Politique
  104.    </div>
  105.    <div cat="Cinema">
  106.    cat Cinema
  107.    </div>
  108.    <div cat="Cinema">
  109.    cat Cinema
  110.    </div>
  111. </div>
  112. </body>
  113. </html>


Message édité par gatsusat le 28-09-2005 à 21:07:17
Reply

Marsh Posté le 28-09-2005 à 21:36:04    

oué, t'as pas pris la meme approche que moi (toi tu fait de la création dynamique dans le code, alors que perso tout est dans un fichier js a coté).
Ca m'empèche de créer des éléments a la volée comme tu le fait.
Dans mon code, les divs des boutons et des news sont générés dynamiquement en php, en fonction du niveau d'identification, etc...
 
ensuite le js est censé récupérer tout ca, browser mon code, en extraire le tableau de boutons et le tableau de liste de news correspondant, et afficher tout ce joli monde ensuite selon les clics.
 
je constate que toi aussi tu as collé un onclick sur un élément créé dans une boucle. Ou est la différence avec mon code dans ce cas ? Le fait que tu sois dans la page meme, alors que moi la page est déja créée ? J'ai un peu de mal a capter, la.  
 
Je comprend bien ton code et les méthodes que tu as choisie, mais je comprend mal pourquoi dans ta boucle a toi, le onclick sait ou il en est alors que dans le mien il est largué)
 
edit : merci de consacrer autant d'attention a mon problème, mais fallait pas te sentir obligé de pondre un exemple complet...


Message édité par Tentac le 28-09-2005 à 21:37:22

---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 21:48:01    

PS : sert toi de mon code je pense que c'est la meilleure méthode en soit.
tu peux aussi le mettre dans un JS à coté, tout sera automatiquement rajouté de toute manière, j'ai tout collé dans la même page afin que tu te rende compte de la chose.
 
Bon ok pour le PHP, mais ca m'a l'air d'être un sacré gros bazar ton code. alors que là je me suis ultra simplifié la vie.
 
Pour en revenir à ton onclick qui est largué je vais texpliquer :
Comme moi tu as un code qui genère les onclick à la volée.
Mais dans ton gros bloc de code, tu as une variable (LC2) qui se balade.
tu rajoute dans ton onclick une fonction contenant LC2
 
MAIS admettons que dans ton onclick tu as juste ca :  
alert(LC2);
 
au moment ou tu rajoutes cette ligne dans la fonction onclick, javascript ne va pas coller la valeur de LC2
ex :  

Code :
  1. LC2 = 45;
  2. truc.onclick = function() {
  3. alert(LC2);
  4. }
  5. LC2++


en admettant que je n'ai que ca comme code
Quand je vais cliquer sur LC2, je n'aurai pas 45 comme resultat, mais 46, car quand tu génère un onclick
la fonction va pas te mettre alert(45) mais bien alert(LC2).
 
Mais moi je me sers d'une value de mon objet lui-même, cette value étant le type de catégorie que tu veux afficher.
et donc avec un this.macat j'ai ma valeur.

Reply

Marsh Posté le 28-09-2005 à 21:59:52    

ok capté, comme onclick est une nouvelle fonction, la valeur d'une variable externe n'est pas récupéré, en fait c'est logique.
Donc en fait, dans mon code, le onclick s'effectue bien sur le bon élément, mais c'est dans la fonction qu'il "perd" la valeur de LC2 et ne sait donc plus quoi en faire.
 
Faut en fait que je trouve une méthode pour récupérer ma variable a l'intérieur de la fonction onclick.
 
Sinon pour info, mon code c'est pas tellement le bordel, c'est juste que je préfère pas générer de html dans mon js, vu que j'en génère déja bien assez dans mon php. De plus, je vais aussi m'arranger pour que mon site puisse fonctionner sans js, et générer du html dans mon js ne me faciliterait pas la tache...


---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 21:59:52   

Reply

Marsh Posté le 28-09-2005 à 22:05:12    

ben JS intrusif c'est lavenir
 
www.c-sait.net
 
desactive le JS (weddevelopper bar sous FF)
tu verras le site est pareil et fonctionnel, mais avec du JS il est magique (cf menu de gauche ou tu peux bouger les blocs)

Reply

Marsh Posté le 28-09-2005 à 22:06:00    

pour info le début du code js c'est ca :
 

Code :
  1. var DIVcoll = document.getElementsByTagName('div');
  2. var LC,LC2;
  3. Divs = new Array();
  4. Butts = new Array();
  5. for (LC2 = 1; LC2 < 5; LC2++)   //je récupère tous mes types de boutons/news
  6. {
  7.  Divs[LC2] = new Array();
  8.  Butts[LC2] = new Array();
  9.  Butts[LC2] = document.getElementById('btype'+LC2);
  10. }
  11. for (LC2 = 1; LC2 < 5; LC2++)   //pour chaque cat' ....
  12. {
  13.  for (LC = 0; LC < DIVcoll.length; LC++)   // je parcours toutes les news...
  14.  {
  15.        if (DIVcoll[LC].className == 'type'+LC2)   //et si la news est dans la bonne cat, je la met dans le tableau qui va bien
  16.   {
  17.   DIVcoll[LC].style.display = 'block';
  18.   Divs[LC2][Divs[LC2].length] = DIVcoll[LC];
  19.     };
  20.  };
  21. }


 
ya moyen de simplifier ca encore, mais bon la j'essaie simplement de faire marcher le tout proprement.


---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 22:10:04    

pourquoi ne pas utiliser mon code ? là tu te complique la vie pour rien du tout !

Code :
  1. for (LC2 = 1; LC2 < 5; LC2++)   //je récupère tous mes types de boutons/news  
  2.     {
  3.         Divs[LC2] = new Array();
  4.         Butts[LC2] = new Array();
  5.         Butts[LC2] = document.getElementById('btype'+LC2);
  6.     }


surtout là ou ca foire un peux pourquoi vouloir faire des tableaux de tableaux ?
 
alors que en englobants tous les éléments dans un bloc
et en faisant monbloc.getElementsByTagName("DIV" ), tu recuperes un tableau de tous tes DIV
 
ya une erreur de conception quelque part là !

Reply

Marsh Posté le 28-09-2005 à 22:28:54    

je capte pas trop ou tu vois un problème...
je récupète tous mes éléments ayant un id de type "btypen", je les met dans un tableau, c'est mes boutons.
je fait de meme pour mes news, selon leur classe de type "typen", je les met dans un tableau.
 
je vois pas ce qui est une erreur de conception la dedans, et pourquoi ca me complique particulièrement la vie. C'est le fait que mes cats soient des numéros ? c'etait voulu a la base, c'est pour rendre l'exploitation plus facile dans mon php.


---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 22:31:41    

le truc c'est que je ne vois pas pourquoi tu les mets dans un tableau
alors qu'avec les méthodes du DOM (getElementByTagName, puis un monobjet.id.indexof("type" )) tu peux t'occuper de tous tes éléments.

Reply

Marsh Posté le 28-09-2005 à 22:45:37    

ca marche, juste en rajoutant un  
LC2 = this.id.substring(5);
dans mon onclick, pour récupérer mon LC2.
Je comprend les méthodes que tu me proposes, mais je vois pas en quoi elles sont mieux/plus simple.
En terme de lignes de codes ca se vaut.
 
le seul truc que mon code ne fait pas, c'est récupérer automatiquement les cats, mais ca je suis en train de le faire, et c'est pareil, pa prend pas plus de 5 lignes
 
merci quand meme pour le coup de main.


Message édité par Tentac le 28-09-2005 à 22:45:55

---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Marsh Posté le 28-09-2005 à 23:09:22    

ben mon code il est peut etre long, mais c'est super clean :(
on s'en fout que le code fasse 5 lignes s'il est incomprehensible et tout pourri.
 
Là il est pas long, j'utilise juste les methodes du DOM a ma sauce et proprement

Reply

Marsh Posté le 28-09-2005 à 23:10:52    

tu adapterai le code que je t'ai donné, tu t'en sortirai mieux

Reply

Marsh Posté le 28-09-2005 à 23:45:54    

en fait, j'ai refait en encore plus simple:

Code :
  1. var LC,LC2,name,num;
  2. News = document.getElementsByTagName('div');
  3. Butts = getElementsByClassName('butt');
  4. for (LC2 = 0; LC2 < Butts.length; LC2++)
  5. {
  6.  Butts[LC2].onclick = function()
  7.     {
  8.   num = this.id.substring(5);
  9.   for (LC = 0; LC < News.length; LC++)
  10.   {
  11.    name = News[LC].className;
  12.    if(name == "type"+num)
  13.    {
  14.     if(News[LC].style.display == ''){News[LC].style.display ='block';}
  15.        if(News[LC].style.display == 'block'){News[LC].style.display ='none';}
  16.     else{News[LC].style.display ='block';}
  17.    }
  18.   }
  19.   return false;
  20.     }
  21. }


 
j'ai juste du coder la fonction get ElementByClassName, qui étrangement n'existe pas (c'est con quand meme, ca peut etre utile....)
 

Code :
  1. function getElementsByClassName( clsName )
  2. {
  3. var arr = new Array();
  4. var elems = document.getElementsByTagName("*" );
  5. for ( var cls, i = 0; ( elem = elems[i] ); i++ )
  6. {
  7.  if ( elem.className == clsName )
  8.  {
  9.   arr[arr.length] = elem;
  10.  }
  11. }
  12. return arr;
  13. }



---------------
"Ramon Balthazard ! Lachez cette arme !"
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed