2017-09-14 1 views
0

dans mon HTML j'ai des questions et des solutions. Je veux cacher et montrer des solutions pour chaque question avec différents boutons.Javascript cacher/montrer avec de nombreux éléments

Voici mon problème: J'écris une nouvelle fonction pour chaque bouton de solution. Par exemple, si j'ai 100 questions, j'ai besoin d'écrire 100 différentes fonctions Javascript.

Y a-t-il une meilleure façon de procéder? Puis-je écrire une seule fonction pour chaque bouton de solution.

Merci beaucoup d'avance.

Voici mon html:

<li>Question 1. What is x?</li> 
<button class="btn btn-outline-success" 
onclick="myFunction()">Solution</button> 
<div id="Solution"> 
<div class="highlight"> 
<pre> 
X is apple 
</pre> 

<li>Question 2. What is y?</li> 
<button class="btn btn-outline-success" 
onclick="myFunction1()">Solution</button> 
<div id="Solution1"> 
<div class="highlight"> 
<pre> 
Y is orange 
</pre> 

Et voici mon Javascript:

document.getElementById('Solution').style.display = 'none'; 

function myFunction() { 
    var x = document.getElementById('Solution'); 
    if (x.style.display === 'none') { 
     x.style.display = 'block'; 
    } else { 
     x.style.display = 'none'; 
    } 
} 

document.getElementById('Solution1').style.display = 'none'; 

function myFunction1() { 
    var x = document.getElementById('Solution1'); 
    if (x.style.display === 'none') { 
     x.style.display = 'block'; 
    } else { 
     x.style.display = 'none'; 
    } 
} 

Note: J'ai vu beaucoup de questions sur cache spectacle, mais je ne pouvais pas résoudre mon problème. Si c'est une question en double s'il vous plaît me prévenir et je peux supprimer.

+0

Est-ce un exercice dans "vanilla JavaScript" i. e. Voulez-vous explicitement éviter d'utiliser jquery? Si oui, cela * peut * être fait, mais sinon, une solution utilisant jquery est presque triviale. – cars10m

+0

Il n'y a aucune raison de préconiser jQuery ici. Cela n'a absolument aucun rapport avec le problème ou la solution. –

+0

Je suis d'accord, si OP veut * résoudre un casse-tête * alors les réponses sans jquery sont justes. Mais s'il veut réaliser quelque chose dans un contexte de mot réel, alors peut-être que l'allusion à jquery pourrait être utile. Je ne le force à personne. Mais '$ ('. Solution'). Hide() $ ('button'). On ('clic', function() {$ (this) .next(). Show()})' est nettement plus court que toutes les autres solutions ici, voir ci-dessous pour une démo de travail. – cars10m

Répondre

1

Vous pouvez réutiliser une seule fonction en passant un argument qui identifie l'élément dans le document doit être montré/caché:

document.getElementById('Solution').style.display = 'none'; 

// The function now expects to be passed the ID of the element 
function myFunction(elementID) { 
    var x = document.getElementById(elementID); 
    if (x.style.display === 'none') { 
     x.style.display = 'block'; 
    } else { 
     x.style.display = 'none'; 
    } 
} 

Maintenant, vous pouvez appeler la fonction à plusieurs reprises et il suffit de passer différents éléments id « s à chaque fois:

<li>Question 1. What is x?</li> 
<button class="btn btn-outline-success" onclick="myFunction('Solution')">Solution</button> 
<div id="Solution"> 
    <div class="highlight"> 
    <pre>X is apple</pre> 
    </div> 
</div> 

<li>Question 2. What is y?</li> 
<button class="btn btn-outline-success" onclick="myFunction('Solution1')">Solution</button> 
<div id="Solution1"> 
    <div class="highlight"> 
    <pre>Y is orange</pre> 
    </div> 
</div> 

maintenant, cela étant dit, vous devriez éviter d'utiliser l'événement HTML en ligne des attributs (onclick, onmouseover, etc.) lorsque cela est possible. Pourquoi many reasons pourquoi. En outre, au lieu de définir de manière répétée des styles en ligne, vous pouvez simplifier la procédure en modifiant l'utilisation d'une classe CSS préexistante. De plus, votre syntaxe HTML est invalide.

Voici à quoi ressemblerait une version nettoyée, valide et moderne de votre code. Tout ce que vous avez à faire est de copier la structure HTML d'une question et le JavaScript existant fonctionnera immédiatement pour cela. Chaque question n'a même plus besoin d'un nom ("Solution1", "Solution2", etc.).

// Get all the buttons in a node list 
 
var theButtons = document.querySelectorAll(".btn-outline-success"); 
 

 
// Turn node list into a JS Array 
 
var buttonArray = Array.from(theButtons); 
 

 
// Loop over the buttons and give each its click event handler 
 
buttonArray.forEach(function(button){ 
 
    button.addEventListener("click", function(){ 
 
    // We will pass a reference to the current button to the function 
 
    myFunction(this); 
 
    }); 
 
}); 
 

 
// The function now expects to be passed a reference to the button that was clicked 
 
function myFunction(element) { 
 
    // Get a reference to div that follows the button and then search that div 
 
    // for the first pre element inside of it: 
 
    var answer = element.nextElementSibling.querySelector("pre"); 
 
    
 
    // All we need to do is toggle the visibility of that pre element 
 
    answer.classList.toggle("hidden"); 
 
}
/* This class will simply be added or removed to show/hide elements */ 
 
/* All answers have this applied by default*/ 
 
.hidden { 
 
    display:none; 
 
} 
 

 
li { margin-bottom:10px; }
<!-- 
 
    NOTES: 
 
      1. The onclick has been removed (it is now handled in JavaScript) 
 
      2. The quesiton names ("Solution", "Solution1", etc.) are no longer needed 
 
      3. Your HTML structure was invalid. Here is the proper way to make bulleted lists. 
 
--> 
 

 
<ul> 
 
    <li>Question 1. What is x? 
 
     <button class="btn btn-outline-success">Solution</button> 
 
     <div> 
 
     <div class="highlight"> 
 
      <pre class="hidden">X is apple</pre> 
 
     </div> 
 
     </div> 
 
    </li> 
 
    
 
    <li>Question 2. What is y? 
 
     <button class="btn btn-outline-success">Solution</button> 
 
     <div> 
 
     <div class="highlight"> 
 
      <pre class="hidden">Y is orange</pre> 
 
     </div> 
 
     </div> 
 
    </li> 
 

 
    <li>Question 3. What is z? 
 
     <button class="btn btn-outline-success">Solution</button> 
 
     <div> 
 
     <div class="highlight"> 
 
      <pre class="hidden">z is mango</pre> 
 
     </div> 
 
     </div> 
 
    </li> 
 
</ul>

+0

Une réponse bien expliquée ;-), +1 – cars10m

+0

Merci beaucoup .. Cela a parfaitement fonctionné dans mon code et me fera gagner beaucoup de temps. J'ai marqué cette réponse comme acceptée. Donc, merci encore beaucoup. –

1

Si je comprends ce que vous voulez, vous pouvez utiliser des paramètres.

HTML

<li>Question 1. What is x?</li> 
<button class="btn btn-outline-success" onclick="myFunction(1)">Solution</button> 
<div id="Solution"></div> 
<div class="highlight"></div> 
<pre> 
    X is apple 
</pre> 

JS

function myFunction(var solNumber = 1) { 
    var x = document.getElementById('Solution'+solNumber); 
    if (x.style.display === 'none') { 
     x.style.display = 'block'; 
    } else { 
     x.style.display = 'none'; 
    } 
} 

Si toutes les questions apparaissent dans le même temps, vous pouvez utiliser une boucle for pour leur montrer trop.

1

Vous pouvez faire quelque chose comme ceci:

  • Enfermez la question dans un div avec classe « question » et solution également jointe à la classe « solution ».
  • Définissez également une seule fonction show avec un paramètre sur lequel l'élément bouton a cliqué, qui est passé en utilisant this comme paramètre dans le onclick du bouton.
  • La fonction trouve simplement la div frères et soeurs avec la 'solution' de classe et le rend visible par la mise display: block

function show_solution(buttonElement) { 
 
    questionDiv = buttonElement.parentNode; 
 
    
 
    if (questionDiv.querySelector('.solution').style.display == 'none') { 
 
    questionDiv.querySelector('.solution').style.display = 'block'; 
 
    } else { 
 
    questionDiv.querySelector('.solution').style.display = 'none'; 
 
    } 
 
    
 
}
.solution { 
 
    display: none; 
 
} 
 

 
.highlight { 
 
    background: #FF0; 
 
}
<div class="question"> 
 
    &bull; Question 1. What is x? 
 
    <button class="btn btn-outline-success" onclick="show_solution(this)">Solution</button> 
 
    <div class="solution"> 
 
    <div class="highlight"> 
 
     <pre> X is apple </pre> 
 
    </div> 
 
    </div> 
 
</div> 
 

 
<div class="question"> 
 
    &bull; Question 2. What is y? 
 
    <button class="btn btn-outline-success" onclick="show_solution(this)">Solution</button> 
 
    <div class="solution"> 
 
    <div class="highlight"> 
 
     <pre> Y is orange </pre> 
 
    </div> 
 
    </div> 
 
</div>

0

Eh bien, si jquery a permis, la solution pourrait ressembler à ceci:

$('.Solution').hide() 
 
$('button').on('click',function(){$(this).next().show()})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<li>Question 1. What is x?</li> 
 
<button class="btn btn-outline-success">Solution</button> 
 
<div class="Solution"> 
 
<div class="highlight"> 
 
<pre> 
 
X is apple 
 
</pre> 
 
</div></div> 
 
<li>Question 2. What is y?</li> 
 
<button class="btn btn-outline-success">Solution</button> 
 
<div class="Solution"> 
 
<div class="highlight"> 
 
<pre> 
 
Y is orange 
 
</pre> 
 
</div></div>

Note: cela aussi simplifier votre code html ... Mais, bien sûr, le choix est le vôtre!

+0

Bonjour, merci pour votre réponse, je ne sais vraiment rien sur jquary. Après votre réponse, je vais commencer à apprendre les bases et pratiquer votre solution. Merci encore beaucoup. –