skip to Main Content

I was building a portfolio website using HTML, CSS, and JavaScript. I encountered an error:

Uncaught type Error allSections.addEventListener is not a function.

I was trying to toggle between the sections of the website using the buttons but they get stuck with the first section, the button clicks don’t take them to the next section.

const sections = document.querySelectorAll('.section');
const sectBtns = document.querySelectorAll('.controls');
const sectBtn = document.querySelectorAll('.control');
const allSections = document.querySelectorAll('.main-content');


function PageTransitions() {
  //buttonclickactiveclass
  for (let i = 0; i < sectBtn.length; i++) {
    sectBtn[i].addEventListener('click', function() {
      let currentBtn = document.querySelectorAll('.active-btn');
      currentBtn[0].className = currentBtn[0].className.replace('active-btn', '');
      this.className += 'active-btn';
    })
  }
  //sections active class
  allSections.addEventListener('click', (e) => {
    const id = e.target.dataset.id;
    if (id) {
      //remove selected from the other btns
      sectBtns.forEach((btn) => {
        btn.classList.remove('active')
      })
      e.target.classList.add('active')

      //hide other class
      sections.forEach((section) => {
        section.classList.remove('active')
      })

      const element = document.getElementById(id);
      element.classList.add('active');
    }
  })

}
PageTransitions();
<!DOCTYPE html>
<html lang="en">

<head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer"
  />
</head>

<body class="main-content">
  <header class="section sec1 header active" data-id="home">

  </header>
  <main>
    <section class="section sec2 about" id="about"></section>
    <section class="section sec3 portfolio" id="portfolio"></section>
    <section class="section sec4 blogs" id="blogs"></section>
    <section class="section sec5 contact" id="contact"></section>
  </main>

  <div class="controls">
    <div class="control control-1 active-btn" data-id="home">
      <i class="fas fa-home"></i>
    </div>
    <div class="control control-2 " data-id="about">
      <i class="fas fa-user"></i>
    </div>
    <div class="control control-3 " data-id="portfolio">
      <i class="fas fa-briefcase"></i>
    </div>
    <div class="control control-4 " data-id="blogs">
      <i class="far fa-newspaper"></i>
    </div>
    <div class="control control-5 " data-id="contact">
      <i class="fas fa-envelope"></i>
    </div>
  </div>

  <script src="app.js"></script>
</body>

</html>

i tried to pass a console.log function but it didnt work too. im hoping someone can help me with this.

2

Answers


  1. querySelectorAll does not return a single element but a node list. Simply use console.log(allSection) or console.log(typeof allSection) and see what it returns. The simple solution is to use a forEach iteration to apply the eventListener to all the elements within the node list:

    allSection.forEach(el =>
      el.addEventListener('click', function(e) {
        ...
      })
    )
    
    const sections = document.querySelectorAll('.section');
    const sectBtns = document.querySelectorAll('.controls');
    const sectBtn = document.querySelectorAll('.control');
    const allSections = document.querySelectorAll('.main-content');
    
    
    function PageTransitions() {
      //buttonclickactiveclass
      for (let i = 0; i < sectBtn.length; i++) {
        sectBtn[i].addEventListener('click', function() {
          let currentBtn = document.querySelectorAll('.active-btn');
          currentBtn[0].className = currentBtn[0].className.replace('active-btn', '');
          this.className += 'active-btn';
        })
      }
      //sections active class
      allSections.forEach(el => el.addEventListener('click', (e) => {
        const id = e.target.dataset.id;
        if (id) {
          //remove selected from the other btns
          sectBtns.forEach((btn) => {
            btn.classList.remove('active')
          })
          e.target.classList.add('active')
    
          //hide other class
          sections.forEach((section) => {
            section.classList.remove('active')
          })
    
          const element = document.getElementById(id);
          element.classList.add('active');
        }
      }))
    
    }
    PageTransitions();
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer"
      />
    </head>
    
    <body class="main-content">
      <header class="section sec1 header active" data-id="home">
    
      </header>
      <main>
        <section class="section sec2 about" id="about"></section>
        <section class="section sec3 portfolio" id="portfolio"></section>
        <section class="section sec4 blogs" id="blogs"></section>
        <section class="section sec5 contact" id="contact"></section>
      </main>
    
      <div class="controls">
        <div class="control control-1 active-btn" data-id="home">
          <i class="fas fa-home"></i>
        </div>
        <div class="control control-2 " data-id="about">
          <i class="fas fa-user"></i>
        </div>
        <div class="control control-3 " data-id="portfolio">
          <i class="fas fa-briefcase"></i>
        </div>
        <div class="control control-4 " data-id="blogs">
          <i class="far fa-newspaper"></i>
        </div>
        <div class="control control-5 " data-id="contact">
          <i class="fas fa-envelope"></i>
        </div>
      </div>
    
      <script src="app.js"></script>
    </body>
    
    </html>
    Login or Signup to reply.
  2. You are selecting all sections with querySelectorAll(). It will return a NodeList which contain list of sections. So, you have to loop over them and then you can use addEventListener().

    There are lot of mistakes and extra code. I have updated the code based on your requirement. Try that:-

    const sections = document.querySelectorAll('.section');
    
    function PageTransitions(){
        sections.forEach(section => {
          section.addEventListener('click',(e)=>{
            const target = e.target;
            const id = target.getAttribute('id');
            if(id){
             // Update active for Section
             document.querySelector('.active').classList.remove('active');
             target.classList.add('active')
             // Update active for Control
             document.querySelector('.active-btn').classList.remove('active-btn');
             document.querySelector('div[data-id="' + id + '"]').classList.add('active-btn')
            }
          });
        })
     
    }
    PageTransitions();
    main{
     display: flex;
     justify-content: space-evenly;
    }
    
    .active{
    background-color: red;
    }
    
    .active-btn{
     background-color: red;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    </head>
    <body class="main-content">
        <main>
        <header class="section sec1 header active" id="home">
             Home Logo
        </header>
            <section class="section sec2 about" id="about">About</section>
            <section class="section sec3 portfolio" id="portfolio">Portfolio</section>
            <section class="section sec4 blogs" id="blogs">Blogs</section>
            <section class="section sec5 contact" id="contact">Contact</section>
        </main>
    
        <div class="controls">
            <div class="control control-1 active-btn" data-id="home">
                <i class="fas fa-home"></i>
            </div>
            <div class="control control-2 " data-id="about">
                <i class="fas fa-user"></i>
            </div>
            <div class="control control-3 " data-id="portfolio">
                <i class="fas fa-briefcase"></i>
            </div>
            <div class="control control-4 " data-id="blogs">
                <i class="far fa-newspaper"></i>
            </div>
            <div class="control control-5 " data-id="contact">
                <i class="fas fa-envelope"></i>
            </div>
        </div>
        
    </body>
    </html>

    I used some lines of CSS for showing the active section and control. Hope it will be helpful.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search