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