Skip to content

Going from JQuery to JavaScript

I have a setup in which you click a question and the answer opens on the right. In previous projects I would’ve used JQuery but this is the first project where it isn’t available.

My markup

<section class="solution-information">
    <div class="container">
        <div class="row">
            <div class="col-12">
                <h3 class="solution-information__title">Your development finance questions, answered</h3>

                <div class="row">
                    {{-- First column --}}
                    <div class="col-12 col-lg-6">
                        <ul class="question-list">
                            <li class="question-list__question" id="question1">
                                What are the criteria to get a development finance loan?
                            </li>

                            <li class="question-list__question" id="question2">
                                What are the criteria to get a development finance loan?
                            </li>

                            <li class="question-list__question" id="question3">
                                What are the criteria to get a development finance loan?
                            </li>
                        </ul>
                    </div>

                    {{-- Second column --}}
                    <div class="col-12 col-lg-6">
                        <div class="question-list__answer d-none" id="answer1">
                            Nulla porttitor accumsan tincidunt. Vivamus suscipit tortor eget felis porttitor volutpat. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Cras ultricies ligula sed magna dictum porta. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Sed porttitor lectus nibh. Cras ultricies ligula sed magna dictum porta.
                        </div>

                        <div class="question-list__answer d-none" id="answer2">
                            Nulla porttitor accumsan tincidunt. Vivamus suscipit tortor eget felis porttitor volutpat. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Cras ultricies ligula sed magna dictum porta. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Sed porttitor lectus nibh. Cras ultricies ligula sed magna dictum porta.
                        </div>

                        <div class="question-list__answer d-none" id="answer3">
                            Nulla porttitor accumsan tincidunt. Vivamus suscipit tortor eget felis porttitor volutpat. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Cras ultricies ligula sed magna dictum porta. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Sed porttitor lectus nibh. Cras ultricies ligula sed magna dictum porta.
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div>
</section>

My JavaScript

<script>
    let question = document.getElementsByClassName('question-list__question');
    let answers = document.getElementsByClassName('question-list__answer');
    let counter;

    for(counter = 0; counter < question.length; counter++){
        question[counter].addEventListener('click', function() {
            this.classList.toggle('question-list__question--selected');

            let number = this.getAttribute("id").substr(this.getAttribute("id").length - 1);

            document.getElementById("answer" + number).classList.toggle('d-none');


        });
    }

</script>

At the moment you can click each question and everything opens. Is there a way to remove the amendments to all other classes so that only one div appears at a time?

Here is the page itself

enter image description here

Is it a case of just looping through the other classes and setting them back to how they were?

Answer

function toggleSelected() {
  // this is what $('...').removeClass('...') does:
  for (let q of document.querySelectorAll('.question-list__question')) {
    q.classList.remove('question-list__question--selected');
  }
  // this is what $('...').addClass('...') does:
  for (let a of document.querySelectorAll('.question-list__answer')) {
    a.classList.add('d-none');
  }

  // ...and now set up the style of *this* element:
  let num = this.getAttribute("id").slice(-1);
  this.classList.add('question-list__question--selected');
  document.querySelector("#answer" + num).classList.remove('d-none');
}

// this is what $('...').click(...) does:
for (let q of document.querySelectorAll('.question-list__question')) {
  q.addEventListener('click', toggleSelected);
}
.question-list__question--selected {
  color: red;
}

.d-none {
  display: none;
}
{{-- First column --}}
<ul class="question-list">
  <li class="question-list__question" id="question1">Question 1</li>
  <li class="question-list__question" id="question2">Question 2</li>
  <li class="question-list__question" id="question3">Question 3</li>
</ul>

{{-- Second column --}}
<div class="question-list__answer d-none" id="answer1">Answer 1</div>
<div class="question-list__answer d-none" id="answer2">Answer 2</div>
<div class="question-list__answer d-none" id="answer3">Answer 3</div>

Obviously jQuery does a little bit more than just wrapping a loop around everything, but at its core, that is what it does. It treats single elements and groups of elements the same way by looping over N-element lists the same way as over 1-element lists (or 0-element lists, which is why jQuery constructs seldom throw errors even if they match nothing).

And if you have more than one element to handle, you need to write those loops yourself.