IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Passage de querySelector à querySelectorAll


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    725
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 725
    Par défaut Passage de querySelector à querySelectorAll
    Bonjour,


    J'ai un script qui fonctionne pour une image.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const imax = document.querySelector ('img.picture');
     
    const tist = imax.alt;
    const idImg = imax.id.split ('X');
    const ca_id = idImg[0];
    const height = idImg[1];
    const img_format = idImg[2];
     
     
    imax.addEventListener ('click', function() {PopGrand (ca_id, tist, height, img_format)});

    À présent il y a plusieurs images, j'ai transformé le script comme suit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const imax = document.querySelectorAll ('img.picture');
     
    for (let i = 0; i < imax.length; i++)
    {
    const tist = imax[i].alt;
    const idImg = imax[i].id.split ('X');
    const ca_id = idImg[0];
    const height = idImg[1];
    const img_format = idImg[2];
     
     
    imax[i].addEventListener ('click', function() {PopGrand (ca_id, tist, height, img_format)});
    }
    Le script fonctionne mais bizarrement il plante tous les autres scripts plus bas dans la page.

    Voyez-vous l'erreur ?

    Merci d'avance.

  2. #2
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 511
    Par défaut
    Bonjour,

    Que voulez-vous dire par planter tous le script en bas de page ? des erreurs, un comportement inattendu ... ?

    Montrez le code qui ne fonctionne pas et expliquez brièvement ce qui se passe pour mieux comprendre le problème.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    725
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 725
    Par défaut
    Merci de votre suivi.

    Les scripts ne s'exécutent pas, je veux dire qu'il ne ne se passe rien sur la page Web.
    Par exemple, un scipt demande de vider un input, il ne se passe plus rien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    const TL = panier.querySelector ('div#TL input');
    TL.addEventListener ('focus', function ()
    {
    if (TL.value == '(texte libre)') TL.value = '';
    else TL.select ();
    }
    );
    Il y a un petit paquet de code.

    Voilà un autre petit script qui ne fonctionne plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const liens = document.querySelectorAll ('#annonce > p > a.cu, #trust > a, div#TL + p > a, p#tot > a, table.compcab th > a, table.compcab td:not(:nth-child(2)) > a:not([title]), .avi > li:nth-child(2) > a, i.trv > a');
     
    for (let i = 0; i < liens.length; i++)
    {
     
    liens[i].addEventListener('click', function (e)
    {
    const win = window.open('nouscab.php#'+this.href.substr (-2),'', 'popup=yes,scrollbars=yes,resizable=yes,width=420,height=420');	
     
    e.preventDefault ();		
    }
    )
    }

    Par contre les scripts placés dans la page avant cette ligne :

    const imax = document.querySelectorAll ('img.picture');

    Ceux-là continuent à bien fonctionner.

    Je peux publier tout le code si vous voulez mais c'est un peu indigeste.

  4. #4
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 511
    Par défaut
    Bonjour,

    Vous n'avez aucune erreur dans le console du navigateur ?

    La cause la plus probable est id.split('X') qui échoue, parce que peut être que le id d'une ou plusieurs image n'est/ne sont pas au format attendu (ca_idXheightXimg_format).

    Si un id ne contient pas le caractère 'X', ou pas assez de fois, alors id.split('X') ne produira pas un tableau avec 3 éléments.

    Par exemple :

    Si id = "monImage", alors id.split('X') donnera un tableau avec une seule valeur ["monImage"].

    idImg[0] sera "monImage" OK.

    idImg[1] sera undefined PAS OK.

    idImg[2] sera undefined PAS OK.

    Et donc si votre fonction PopGrand (ou n'importe quelle opération en aval) essaie d'utiliser height ou img_format (qui seraient undefined dans ce cas) comme s'ils étaient des chaînes de caractères ou des nombres valides, cela va provoquer une erreur.

    Si PopGrand fait height.toFixed(2) ou img_format.toUpperCase(), et que height ou img_format est undefined, JavaScript lancera une erreur du type "Cannot read properties of undefined (reading 'toFixed')" ou "Cannot read properties of undefined (reading 'toUpperCase')". Cette erreur stoppe tout !

    La solution : Sécuriser votre code
    Vous devez ajouter des vérifications pour vous assurer que les parties de l'ID existent avant de les utiliser. Voici comment adapter votre script en utilisant forEach(ce qui est plus propre pour les NodeListet aide à la clarté) et en ajoutant les vérifications nécessaires :
    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
    // Votre script principal pour les images
    const imaxes = document.querySelectorAll('img.picture'); // Renommé en imaxes pour plus de clarté
     
    imaxes.forEach(imax => {
      const tist = imax.alt;
      const idImg = imax.id.split('X');
     
      // --- VÉRIFICATION CRUCIALE ICI ---
      // S'assurer que le tableau idImg a au moins 3 éléments
      if (idImg.length < 3) {
        console.error(`Erreur : L'ID de l'image "${imax.id}" n'a pas le format attendu (ca_idXheightXformat).`);
        // Optionnel : Vous pouvez choisir d'ignorer cet écouteur pour cette image
        return; // Passe à l'image suivante de la boucle forEach
      }
      // --- FIN DE LA VÉRIFICATION ---
     
      const ca_id = idImg[0];
      const height = idImg[1];
      const img_format = idImg[2];
     
      imax.addEventListener('click', function() {
        // Les variables ca_id, tist, height, img_format sont correctement capturées pour chaque image
        PopGrand(ca_id, tist, height, img_format);
      });
    });
     
    // Vos autres scripts devraient maintenant fonctionner car le script précédent ne plante plus
     
    // Votre script pour vider l'input
    const TL = document.querySelector('div#TL input');
    if (TL) { // Toujours vérifier que l'élément existe avant d'ajouter un écouteur
      TL.addEventListener('focus', function() {
        if (TL.value === '(texte libre)') { // Utilisez === pour une comparaison stricte
          TL.value = '';
        } else {
          TL.select();
        }
      });
    }
     
    ---
     
    // Votre script pour les liens
    const liens = document.querySelectorAll('#annonce > p > a.cu, #trust > a, div#TL + p > a, p#tot > a, table.compcab th > a, table.compcab td:not(:nth-child(2)) > a:not([title]), .avi > li:nth-child(2) > a, i.trv > a');
     
    // Utilisez forEach, c'est plus moderne et moins sujet aux erreurs de closure, même si votre for (let i...) était correct
    liens.forEach(lien => {
      lien.addEventListener('click', function(e) {
        // Assurez-vous que this.href est ce que vous attendez. substr(-2) semble un peu court pour un hash.
        // Peut-être this.getAttribute('href') ou this.dataset.someId ?
        const hrefPart = this.href.substr(-2); // Vérifiez que cela donne bien la partie que vous voulez
        const win = window.open('nouscab.php#' + hrefPart, '', 'popup=yes,scrollbars=yes,resizable=yes,width=420,height=420');
     
        e.preventDefault();
      });
    });

    Pourquoi l'erreur est cruciale

    Imaginez votre page web comme une ligne de production. Chaque script est une étape. Si une étape échoue (une erreur non gérée), toute la chaîne s'arrête. C'est exactement ce qui se passe ici. Le console.error() que j'ai ajouté dans le code de l'image vous montrera un message d'erreur clair dans la console de développement de votre navigateur si une image a un ID mal formaté.

    Étapes pour déboguer :
    • Mettez à jour votre code avec les vérifications idImg.length < 3 et l'utilisation de forEach au lieu de for.
    • Ouvrez les outils de développement de votre navigateur (F12 sur Chrome/Firefox, ou clic droit -> Inspecter).
    • Allez à l'onglet "Console" pour voir les erreurs et les messages de console.log() ou autre ...
    • Rechargez votre page.
    • Si des IDs sont mal formatés, vous verrez des messages d'erreur "Erreur : L'ID de l'image..." dans la console. Cela vous aidera à identifier quelles images posent problème.


    En résolvant cette erreur cachée dans la boucle des images, les scripts suivants sur votre page devraient de nouveau s'exécuter normalement.

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 474
    Par défaut
    Hello,

    Comme indiqué par Toufik83, nous avons besoin de savoir quel navigateur tu utilises et si tu sais comment ouvrir la console Javascript (laquelle contiendra à coup sûr un message d'erreur si celle-elle se produit)

    Citation Envoyé par boteha Voir le message
    Le script fonctionne mais bizarrement il plante tous les autres scripts plus bas dans la page.
    Cela peut arriver typiquement — quand la console est fermée — parce qu'une erreur se produit juste après la boucle que tu nous as montrée. Cela peut être une simple erreur de syntaxe, comme quelque chose de plus évolué. Dans tous les cas, au moins avec Firefox, l'exécution du script sera interrompue à partir de cet endroit mais tout ce qui aura été exécuté jusque là restera en l'état… notamment la mise en place d'écouteurs appelant des fonctions de callback. Ceci pouvant te donner l'impression que le Javascript est toujours actif et que la totalité du script reste fonctionnelle, ce qui n'est pas le cas.

    Quand la console de déboguage est ouverte (au moins sous Firefox, encore une fois), le navigateur lève une exception et le traitement complet de la page est suspendu en attendant une intervention de ta part depuis le débogueur. Il est donc moins facile de rater l'erreur…

    Voyez-vous l'erreur ?
    Pas en l'état, mais on peut quand même te donner quelques conseils :

    • Si « (texte libre) » est une indication donnée à l'utilisateur pour qu'il sache quoi rentrer dans le champ, alors il existe l'attribut placeholder qui fait ce travail pour toi. Tu pourras donc éliminer cette section du Javascript ;
    • Depuis un peu plus d'une dizaines d'année, un foreach est disponible en Javascript. for(const e of imax) te permet d'itérer directement sur chaque élément du tableau imax, avec ici une référence vers chaque élément dans e, qui peut prendre n'importe quel autre nom ;
    • Si la fonction PopGrand n'est utilisée que par les éléments img.picture de ta boucle, alors tu aurais tout intérêt à l'associer directement en tant qu'Event Listener et lui laisser faire elle-même tout le travail d'extraction que tu fais dans ta boucle.


    Ainsi, sur ce dernier point, tu écrirais directement :

    Code Javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for (const image of imax)
        image.addEventListener('click', PopGrand);

    Ta fonction ne prendrait alors plus qu'un seul argument et plus quatre :

    Code Javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    function PopGrand (event) {}

    Et à l'intérieur de ta fonction, tu utilises event.target pour récupérer l'élément ciblé et tu fais à cet endroit les calculs que tu faisais jusqu'à présent dans la boucle qui te pose problème. Parce qu'en l'état actuel des choses, il y a plusieurs choses qu'il faut prendre en compte :

    1. Les variables qui étaient jusqu'ici globales deviennent locales une fois embarquées au sein de ta boucle ;
    2. Comme leurs références sont détruites et réallouées à chaque tour de boucle, il faut tenir compte de leur durée de vie, spécialement quand tu les passes à la fonction lambda qui n'est pas encore appelée au moment où tu fais ces initialisations.


    Normalement, les mécanisme de closure de la fonction lambda devraient assurer le comportement que tu cherches à obtenir, mais seulement à l'issue d'une procédure bien plus complexe qu'on l'imagine, surtout s'il faut tenir compte des passages par valeur sur tous les types natifs (formellement les nombres, ici) et les objets passés par référence.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    725
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 725
    Par défaut
    Bonjour,

    Merci beaucoup pour vos réponses approfondies.

    Si je fais un copier-coller du code de Toufik83 cela fonctionne.

    Mais il y a quand même un problème.

    En l'occurrence il n'y a qu'un seul élément img.picture et son id est bien formaté.

    Je n'ai aucun problème avec le selecteur querySelector.

    Je vais bientôt avoir plusieurs éléments img.picture c'est pourquoi je passe à querySelectorAll et je commence par un test avec un seul élément img.picture (ce qui correspond toujours à un cas réel, disons qu'il peut y avoir de une à six images).

    Et l'erreur console est que ca_id n'est pas défini.

    Cela correspond bien à votre diagnostic.
    Mais pourquoi sortir un ca_id non défini alors qu'il n'y a qu'une seule image et que le ca_id est bien trouvé et bien utilisé dans PopGrand qui s'exécute?

    Et le nouveau problème est que j'ai besoin de ca_id dans la suite du script, donc cela plante.

    C'est comme si querySelectorAll mettait dans la boucle un élément pourri.

    Avez-vous une idée ?


    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
    const imaxes = document.querySelectorAll('img.picture'); // Renommé en imaxes pour plus de clarté
     
    imaxes.forEach(imax => {
      const tist = imax.alt;
      const idImg = imax.id.split('X');
     
      // --- VÉRIFICATION CRUCIALE ICI ---
      // S'assurer que le tableau idImg a au moins 3 éléments
      if (idImg.length < 3) {
        console.error(`Erreur : L'ID de l'image "${imax.id}" n'a pas le format attendu (ca_idXheightXformat).`);
        // Optionnel : Vous pouvez choisir d'ignorer cet écouteur pour cette image
        return; // Passe à l'image suivante de la boucle forEach
      }
      // --- FIN DE LA VÉRIFICATION ---
     
      const ca_id = idImg[0];
      const height = idImg[1];
      const img_format = idImg[2];
     
      imax.addEventListener('click', function() {
        // Les variables ca_id, tist, height, img_format sont correctement capturées pour chaque image
        PopGrand(ca_id, tist, height, img_format);
      });
    });
     
    /*
    Et c'est là que cela va planter car ca_id qui pourtant a bien été utilisé dans PopGrand est devenu indéterminé.
    Comme j'ai besoin de ca_id je ne peux pas m'en sortir avec un test if (typeof ca_id !== 'undefined')
    */
     
    let idPreco = document.getElementById ('F'+ ca_id);

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    725
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 725
    Par défaut
    Citation Envoyé par Obsidian
    Si la fonction PopGrand n'est utilisée que par les éléments img.picture de ta boucle, alors tu aurais tout intérêt à l'associer directement en tant qu'Event Listener et lui laisser faire elle-même tout le travail d'extraction que tu fais dans ta boucle.
    Cette fonction est utilisée dans une autre boucle.
    Mais les deux boucles ne seront pas utilisées simultanément, c'est l'une ou l'autre selon le nombre d'un certain élément dans la page.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function PopGrand (ca_id, tist, height, img_format)
    {
    if (!mobile.matches) {return false;}
    else
    {
    const win = window.open ('popup.php?nom='+ encodeURI (ca_id+'G.'+img_format+'&tit='+tist), '', 'popup=yes,scrollbars=yes,resizable=yes,width=420,height='+height);
    }
    }

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    725
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 725
    Par défaut
    Mon problème n'est_il pas de 'sortir' ca_id de la boucle foreach afin de la transmettre aux scripts suivants ?

    Je précise que quel que soit le nombre d'images ca_id aura toujours la même valeur.

    Avec querySelector la variable ca_id est disponible.

    Avec querySelectorAll il faut la "sortir" ce que je ne sais pas faire.

    Est-ce une bonne piste ?

  9. #9
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 511
    Par défaut
    Citation Envoyé par boteha Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    const imaxes = document.querySelectorAll('img.picture'); // Renommé en imaxes pour plus de clarté
    ......
    /*
    Et c'est là que cela va planter car ca_id qui pourtant a bien été utilisé dans PopGrand est devenu indéterminé.
    Comme j'ai besoin de ca_id je ne peux pas m'en sortir avec un test if (typeof ca_id !== 'undefined')
    */
     
    let idPreco = document.getElementById ('F'+ ca_id);
    Et pourquoi ne pas déplacer les scripts qui utilisent ca_id à l'intérieur de la boucle forEach ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // ce qui précède....
      const ca_id = idImg[0];
      const height = idImg[1];
      const img_format = idImg[2];
     
      imax.addEventListener('click', function() {
        // Les variables ca_id, tist, height, img_format sont correctement capturées pour chaque image
        PopGrand(ca_id, tist, height, img_format);
      });
      // ICI PAR EXEMPLE 
      let idPreco = document.getElementById ('F'+ ca_id);
    Notez qu'après (à l'extérieur de) la boucle , ca_id vaut toujours à L'ID de la dernière image parcourue c'est pour ça que la valeur est toujours la même, la dernière....

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    725
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 725
    Par défaut
    Merci de votre suivi.

    Citation Envoyé par Toufik83
    Et pourquoi ne pas déplacer les scripts qui utilisent ca_id à l'intérieur de la boule forEach ?
    La boucle concerne les images et les scripts suivants concerne le produit.

    Cela me semble peu économique de faire tourner dans une boucle des scripts qui ne nécessitent d'être écrits qu'une seule fois.

    Je connais mal Js mais je suppose qu'il existe un moyen de sortir ca_id de la boucle, ce serait enfantin avec PHP.

    J'ai essayé return ca_id mais cela semble ne pas marcher.

    Autrement je vais chercher un autre moyen de récupérer cette variable dans le html.

    Citation Envoyé par Toufik83
    Notez qu'après (à l'extérieur de) la boucle , ca_id vaut toujours à L'ID de la dernière image parcourue c'est pour ça que la valeur est toujours la même, la dernière....
    Oui, c'est noté.

  11. #11
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 511
    Par défaut
    Bonjour,
    Citation Envoyé par boteha Voir le message
    Cela me semble peu économique de faire tourner dans une boucle des scripts qui ne nécessitent d'être écrits qu'une seule fois.
    C'est normal, et je pense que ça n'a aucun impact sur l'ergonomie et la performance de code, d'ailleurs c'est ce qu'on fait tous.

    La preuve c'est que l'événement click est écrit une seule fois mais utilisé plusieurs fois avec des valeurs de paramètres différentes.

    Citation Envoyé par boteha Voir le message
    Autrement je vais chercher un autre moyen de récupérer cette variable dans le html.
    J'en doute fort que vous puissiez trouver une solution adapté à votre situation, à moins qu'ils y a d'autres chose que vous n'avez pas mis dans la discussion.

Discussions similaires

  1. [AC-2019] Passage d'un document mdb à un document abbdb
    Par jl11200 dans le forum VBA Access
    Réponses: 2
    Dernier message: 04/05/2020, 15h12
  2. document.querySelectorAll() ne fonctionne plus du jour au lendemain
    Par fullmetalkeke dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/07/2013, 14h30
  3. passage variable dans document.location.href
    Par tilily dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 24/11/2010, 21h59
  4. Réponses: 6
    Dernier message: 21/01/2008, 18h49
  5. Passage de parametre d'un document Flash vers un servlet ?
    Par haifa28 dans le forum Servlets/JSP
    Réponses: 7
    Dernier message: 09/04/2007, 06h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo