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 :

Spoiler et lecture audio


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Electronicien
    Inscrit en
    Juillet 2016
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Electronicien

    Informations forums :
    Inscription : Juillet 2016
    Messages : 10
    Par défaut Spoiler et lecture audio
    Bonjour à tous,

    je suis débutant en développement web et je rencontre un petit soucis avec un premier programme en javascript.

    le contexte: je donne des cours de français (en amateur) et je souhaiterais créer un mini site web qui me servira de support pour les cours.
    les pages web contiennent des fichiers audios et de petits exercices.
    Au début je codais tout en html pour intégrer les fichiers audios de type :

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <table>
            <tr><th>🇪🇦</th><th class="fleche"></th><th>🇲🇫</th><th class="audio"><i class="fas fa-volume-up"></i></th></tr>
            <tr><td>posible</td><td class="fleche"></td><td>possible</td><td><audio id="player1"><source src="html/francais/media/possible.ogg" type="audio/ogg"></audio><button onclick="document.getElementById('player1').play()"><i class="far fa-play-circle"></i></button></td></tr>
            <tr><td>probable</td><td class="fleche"></td><td>probable</td><td><audio id="player2"><source src="html/francais/media/probable.ogg" type="audio/ogg"></audio><button onclick="document.getElementById('player2').play()"><i class="far fa-play-circle"></i></button></td></tr>
          </table>

    le problème est que ça me prend un temps fou! J'ai donc décidé de simplifier et d'automatiser tout ça avec un peu de javascript pour arriver à ça:

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <table>
            <tr><th>🇪🇦</th><th class="fleche"></th><th>🇲🇫</th></tr>
            <tr><td>posible</td><td class="fleche"></td><td class="play">possible </td></tr>
            <tr><td>probable</td><td class="fleche"></td><td class="play">probable </td></tr>
    </table>

    Ce qui est déjà beaucoup mieux et cela fonctionne très bien.
    L'idée est de : détecter la class "play" -> utiliser le texte pour générer un nom de fichier -> ajouter un bouton pour lire le fichier
    J'ai donc voulu continuer sur la même voie en ajoutant un "spoiler" pour masquer les réponses des exercices.

    Celui-ci fonctionne très bien aussi mais une fois la réponse dévoilée, il est impossible d'écouter le fichier audio.
    En résumé la "fonction play" et la "fonction spoiler" fonctionne séparément mais pas ensemble.. et c'est là que je viens vous demander un peu d'aide!

    voici le code et une "page test" (audio + avec et sans spoiler)

    HTML
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <body>
        <div class="exercice">
            <div class="exercice-content">
                <h3>¿Cómo dirias?</h3>
                <ul>
                  <li><span class="question">es para ti</span><span class="play">c'est pour toi </span></li>
                  <li><span class="question">no es para mi</span><span class="spoiler play ">ce n'est pas pour moi </span></li>
                  <li><span class="question">es posible para ti</span><span class="spoiler play">c'est possible pour toi </span></li>
                  <li><span class="question">para mi, no es aceptable</span><span class="spoiler play">pour moi, ce n'est pas acceptable </span></li>
                </ul>
            </div>
          </div>
       <script type="text/javascript" src="test.js"></script>
    </body>

    JAVASCRIPT
    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
    //--------------- BOUTON PLAY----------------
     
    //sélectionner tous les éléments avec la class .play
    let playElements = document.querySelectorAll(".play");
     
    //conversion du texte en nom de fichier
    function convertTextToFile(txtToConvert) {
         txtToConvert = txtToConvert.toLowerCase();
        let rules = {
          'a': /[àáâãäå]+/g,
          'ae': /[æ]+/g,
          'c': /[ç]+/g,
          'e': /[èéêë]+/g,
          'i': /[ìíîï]+/g,
          'n': /[ñ]+/g,
          'o': /[òóôõöø]+/g,
          'oe': /[œ]+/g,
          'u': /[ùúûü]+/g,
          'y': /[ýÿ]+/g,
          '_': /[\s\',]+/g,
          '': /[?!.]+/g
        };
        for (let r in rules) txtToConvert = txtToConvert.replace(rules[r], r);
        txtToConvert =  "html/francais/audio/" + txtToConvert + ".ogg";
        console.log(txtToConvert);
        return txtToConvert;
    }
     
    //créer un bouton Play pour lire un fichier audio
    let createPlayButton = function(play, txtConverted){
     
      //création du bouton play
      let playButton = document.createElement("button");
      playButton.textContent = "⯈";
     
      //ajout du bouton au DOM
      play.appendChild(playButton);
     
      //action du clic
      playButton.addEventListener("click", function(){
        let audioElement = new Audio(txtConverted);
        audioElement.play();
        console.log(audioElement);
      })
    }
     
    //parcourir tous les éléments .play, convertir et inserer le bouton
    for(let i = 0; i < playElements.length; i++){
        let txtToConvert = playElements[i].innerText;
        createPlayButton(playElements[i], convertTextToFile(txtToConvert));
      }
     
     
    //--------------- SPOILER ----------------
     
    //sélectionner tous les éléments avec la class .spoiler
    let elements = document.querySelectorAll(".spoiler");
     
    //créer un bouton + <span> qui contiendra le spoiler
    let createSpoilerButton = function(element){
     
      //création d'une <span>
      let span = document.createElement("span"); //création d'une <span>
      span.className = "spoiler-content"; //ajout d'une class .spoiler-content a la <span>
      span.innerHTML = element.innerHTML; //ajout du texte html à l'intérieur de la <span>
     
     
      //création du bouton spoiler
      let spoilerButton = document.createElement("button"); //création du bouton
      spoilerButton.textContent = "➠ Ver la respuesta";
     
      //ajout des éléments au DOM
      element.innerHTML = ""; //nettoie l'élément html
      element.appendChild(spoilerButton); //ajout du bouton à l'élément
      element.appendChild(span); //ajout de la <span> à l'élément
     
     
      //action du click
      spoilerButton.addEventListener("click", function(){
        spoilerButton.parentNode.removeChild(spoilerButton); //suppression du bouton
        span.classList.remove("spoiler-content");
        span.classList.add("spoiler-content-visible"); //ajout de la class .spoiler-content-visible
      })
    }
     
    //parcourir tous les éléments .spoiler et appliquer le spoiler
    for(let i = 0; i < elements.length; i++){
      createSpoilerButton(elements[i])
    }
    Code CSS : 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
    .exercice{
        text-align: center;
    }
     
    .exercice-content
    {
        display: inline-block;
        border: 3px dashed rgba(49,130,189,.8);
        border-radius: 10px;
        overflow: hidden;
        max-width: 80%;
    }
     
    .exercice-content li {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        padding: 5px;
    }
     
    .exercice-content .question{
        display: inline-block;
        padding: 6px 10px 0 0;
    }
     
    .spoiler-content {
      display: inline-block;
      width: 0;
      height: 0;
      opacity: 0;
      overflow: hidden;
      transition: opacity 0.5s;
    }
     
    .spoiler-content-visible {
      display: inline-block;
      width: auto;
      height: auto;
      opacity: 1;
      padding: 0;
      padding-bottom: 1px;
    }
     
    .spoiler-content-visible::before {
        content: " ➠ ";
        font-size: 1rem;
     
    }
     
    .spoiler {
        display: block;
        margin-right: 20px;
        margin-left: 10px;
    }

    Le code du "spoiler" est inspiré d'un tuto de Grafikart et celui de la conversion de texte en nom de fichier vient d'un post de ce forum (mais je ne me rappelle plus qui en est l'auteur).
    J'espère qu'il ne manque rien comme informations et que je n'ai pas été trop confus dans mes explications.
    Je vous remercie d'avance pour votre aide !

    Damien

  2. #2
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 580
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 580
    Par défaut
    le souci est à la ligne 65 de votre code javascript. vous récupérez le "innerHTML" donc la balise bouton, mais vous perdez l'évènement associé au bouton.

    vous pouvez corrigez cela en créant les zones de spoil en premier et en ajoutant dans un second temps les boutons.

  3. #3
    Membre habitué
    Homme Profil pro
    Electronicien
    Inscrit en
    Juillet 2016
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Electronicien

    Informations forums :
    Inscription : Juillet 2016
    Messages : 10
    Par défaut
    Bonjour et merci pour ta réponse!
    Maintenant je comprends bien le problème, même si je n'arrive toujours pas le résoudre..

    Je tente de garder les deux fonctions "séparées", j'entends par là qu'un "spoil" peut être appliqué sans que nécessairement un bouton audio soit créé (et vice-versa). Le plus simple serait sûrement de créer une troisième fonction de type spoil_play qui cumulerait les deux mais comme je suis un peu idiot et que j'aime bien les défis, je me suis dit qu'en premier je tenterai d'en utiliser seulement deux.

    Pour cela je pensais faire dans la fonction "createSpoilerButton" une "détection" de la classe .play et si elle est présente, lors d'un clic sur le spoiler, de créer un nouveau bouton play et supprimer l'ancien.
    mais pour l'instant je n'ai pas réussi, et en tant que grand débutant je ne sais pas si c'est la bonne méthode. J'essaie d'éviter autant que possible les bidouilles, les variables globales et d'avoir un code propre pour ne pas prendre de mauvaises habitudes.

    Bon allez, j'y retourne.. et encore merci!!

    EDIT :
    A peine avoir posté ce message m'est apparue la solution..
    dans la fonction "createSpoilerButton" dans l'action du clic j'ai ajouté une condition :
    Code Javascript : 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
     
    //action du click
      spoilerButton.addEventListener("click", function(){
        spoilerButton.parentNode.removeChild(spoilerButton); //suppression du bouton
        span.classList.remove("spoiler-content");
        span.classList.add("spoiler-content-visible"); //ajout de la class .spoiler-content-visible
     
        //detection d'une classe play
        let elementClasse = element.className; 
        let testClasse = elementClasse.indexOf("play");
          if (testClasse !== -1){
            bouton = element.querySelector("button");
            bouton.remove("button");
            let txtToConvert = span.innerText;
            createPlayButton(element, convertTextToFile(txtToConvert))
          }
      })

    Afin de cloturer le sujet, une dernière question :
    D'après vous, c'est propre comme méthode ? ou au contraire c'est bancale?

    Merci beaucoup!

Discussions similaires

  1. Problèmes de lectures audio/vidéo
    Par Z20500 dans le forum Vidéo
    Réponses: 1
    Dernier message: 11/08/2008, 11h11
  2. Pilote pour lecture audio
    Par Masterglob dans le forum API, COM et SDKs
    Réponses: 5
    Dernier message: 29/05/2008, 12h19
  3. [Libraire] Son , lecture audio.
    Par RideKick dans le forum Windows Forms
    Réponses: 2
    Dernier message: 09/07/2007, 13h51
  4. lecture audio auto une fois
    Par vincz dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 23/05/2007, 08h06
  5. [JavaSound] Problème de lecture audio
    Par jbond008 dans le forum Multimédia
    Réponses: 2
    Dernier message: 09/05/2007, 10h56

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