简体   繁体   中英

In javascript, how do I remove previously clicked sibling div, so that only one answer displays at a time?

I must use a for loop to go through the h2 elements in the array and remove the class attribute for all h2 elements that aren't the one that has been clicked. I also need to remove the class attributes for all of the div siblings of the h2 elements that weren't clicked, but I am not sure how to do this. The code I am trying to use is under the "//remove all other answers" comment. Please help me out, thanks!

 var toggle = function() { var h2 = this; // clicked h2 tag var div = h2.nextElementSibling; // h2 tag's sibling div tag // toggle plus and minus image in h2 elements by adding or removing a class if (h2.hasAttribute("class")) { h2.removeAttribute("class"); } else { h2.setAttribute("class", "minus"); } // toggle div visibility by adding or removing a class if (div.hasAttribute("class")) { div.removeAttribute("class"); } else { div.setAttribute("class", "open"); } //remove all other answers var faqs = $("faqs"); var h2Elements = faqs.getElementsByTagName("h2"); for (var i = 0; i < h2Elements.length; i++ ) { if(!h2Elements.onclick) { h2.removeAttribute("class", "minus"); } else { h2Elements.onclick; } } }; 
 <body> <main id="faqs"> <h1>JavaScript FAQs</h1> <h2><a href="#" >What is JavaScript?</a></h2> <div id="1"> <p>JavaScript is a is a browser-based programming language that makes web pages more responsive and saves round trips to the server. </p> </div> <h2><a href="#">What is jQuery?</a></h2> <div id="2"> <p>jQuery is a library of the JavaScript functions that you're most likely to need as you develop websites. </p> </div> <h2><a href="#">Why is jQuery becoming so popular?</a></h2> <div id="3"> <p>Three reasons:</p> <ul> <li>It's free.</li> <li>It lets you get more done in less time.</li> <li>All of its functions are cross-browser compatible.</li> </ul> </div> </main> </body> 

There is an easy common pattern for your type of problem. Give all questions a single, shared classname. Then on click

  1. use document.getElementsByClassName with the shared classname and apply css display:"none" (or a class that achieves this style) on all elements
  2. set display:"block" or display:"inline" on the current selection

You've wrapped all this code in your toggle function, but the function is not called anywhere.

You should attach the event listener to your h2 tags after defining them with jQuery.

The order of your set/remove attributes is a little off.

Try coming this working example to your code:

var h2 = $("h2");
    h2.on('click', function() {
        for (var i = 0; i < h2.length; i++) {    
            if (h2[i] !== this) {
                h2[i].setAttribute('class', 'red');
            } else {
                h2[i].removeAttribute('class', 'red');
            }
        }
    })

I've use the example class red here if you wanted to say, toggle the color in your CSS. You can use whatever class here in place of my example.

Hope this helps. What I have done is I hide all div(and remove class red from all h2 tag other than one which is click in for loop) and toggle clicked h2 and it's sibling.

 function func(e){ var x=document.getElementsByClassName("ans"); for(var i=0;i<x.length;i++){ if(x[i].classList.value.indexOf("hide")<0 && x[i]!==e.nextElementSibling){ x[i].classList.toggle("hide"); x[i].previousElementSibling.classList.toggle("red"); } } e.classList.toggle("red"); e.nextElementSibling.classList.toggle("hide"); } 
 .red{ background-color:red; } .hide{ display:none; } 
 <body> <main id="faqs"> <h1>JavaScript FAQs</h1> <h2 onclick="func(this)"><a href="#" >What is JavaScript?</a></h2> <div id="1" class="ans hide"> <p>JavaScript is a is a browser-based programming language that makes web pages more responsive and saves round trips to the server. </p> </div> <h2 onclick="func(this)"><a href="#">What is jQuery?</a></h2> <div id="2" class="ans hide"> <p>jQuery is a library of the JavaScript functions that you're most likely to need as you develop websites. </p> </div> <h2 onclick="func(this)"><a href="#">Why is jQuery becoming so popular?</a></h2> <div id="3" class="ans hide"> <p>Three reasons:</p> <ul> <li>It's free.</li> <li>It lets you get more done in less time.</li> <li>All of its functions are cross-browser compatible.</li> </ul> </div> </main> </body> 

This example should accomplish what you've outlined in your question. Here I'm looping through all H2 elements and processing the one that was clicked separately.

 $('h2').on('click',function(){ var thisH2 = this; $('h2').each(function(){ if (this === thisH2){ if ($(this).next().is(":visible")){ $(this).removeClass('plus').addClass('minus'); $(this).next().hide(); }else{ $(this).removeClass('minus').addClass('plus'); $(this).next().toggle(); } }else{ $(this).removeClass('plus').addClass('minus'); $(this).next().hide(); } }); }); 
 h2{ cursor:pointer; } h2:hover{ text-decoration:underline; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> <main id="faqs"> <h1>JavaScript FAQs</h1> <h2 class="minus">What is JavaScript?</h2> <div class="answer" style='display:none'> <p>JavaScript is a is a browser-based programming language that makes web pages more responsive and saves round trips to the server. </p> </div> <h2 class="minus">What is jQuery?</h2> <div class="answer" style='display:none'> <p>jQuery is a library of the JavaScript functions that you're most likely to need as you develop websites. </p> </div> <h2 class="minus">Why is jQuery becoming so popular?</h2> <div class="answer" style='display:none'> <p>Three reasons:</p> <ul> <li>It's free.</li> <li>It lets you get more done in less time.</li> <li>All of its functions are cross-browser compatible.</li> </ul> </div> </main> </body> 

To help you identify your sections from your Subheadings

Add this to all sections you can use different identifiers

I'd suggest adding a class or attribute

<h2><a href="#" class="1">What is JavaScript?</a></h2>
<div class="section" id="1">

This will enable us to select all the divs will the class section

const sections = document.querySelectorAll('.section')

Then we can loop over them all and add the minus class I'd suggest just adding this in the mark up if you intend this to be your default state.

sections.forEach(el => {
  el.classList.add('minus')
});

Now we can loop over all your anchor tags I'd suggest giving them an identifier such as a class to separate them from other anchor tags but the example i'll just select all the anchor tags. We attach a function reference to the on click of the element called openSection which we'll define shortly.

document.querySelectorAll('a').forEach((el, index) => {
  el.onclick = openSection;
})

Now, this is the function that will toggle your minus and remove it from other items

Your function gets passed an event which will contain the information we need to get the correct section to hide. We loop through the sections and remove minus with toggle if it matches the element clicked and then any other item if it doesn't have minus it gets added on to make sure it's hidden.

function openSection(e) {
  // we use - 1 because lists start at 0
  const el = e.srcElement.classList.value - 1;
  sections.forEach((section, index) => {
    if (index === el) {
      section.classList.toggle('minus')
    } else if (!section.classList.contains('minus')) {
      section.classList.add('minus')
    }
  })
}

Working example

https://codepen.io/anon/pen/KoWgwm

Stuff used

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM