You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Uncaught TypeError: addEventListener不是函数错误求助(VS Code无提示)

解决allSections.addEventListener is not a function错误

控制台持续抛出错误:

Uncaught TypeError: allSections.addEventListener is not a function
at PageTransitions (app.js:16:17)
at app.js:33:1

VS Code编辑器中无错误提示,以下是相关代码:

JavaScript代码

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

function PageTransitions(){
    
    for(let i = 0; i < secBtn.length; i++){
        secBtn[i].addEventListener('click', function(){
            let currentBtn = document.querySelectorAll('.active-btn');
            currentBtn[0].className = currentBtn[0].className.replace('active-btn', '')
            this.className += ' active-btn';
        })
    }

    allSections.addEventListener('click', (e) =>{
        const id = e.target.dataset.id;
        if(id) {
            secBtns.forEach((btn) => {
                btn.classList.remove('active')
            })
            e.target.classList.add('active')
            sections.forEach((section)=>{
                section.classList.remove('active')
            })

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

PageTransitions();

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Portfolio</title>
    <link rel="stylesheet" href="styles/styles.css">
    <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<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" />
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital@1&family=Ubuntu:wght@300&display=swap" rel="stylesheet">
</head>
<body class="main-content">
    <header class="section sec1 header active" 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 contacts" 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-open"></i>
        </div>

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

错误原因及解决方案

核心问题

document.querySelectorAll('.main-content')返回的是NodeList集合(即使页面中只有一个匹配元素),而addEventListener是单个DOM元素的方法,集合无法直接调用该方法,因此抛出类型错误。

从HTML代码可以看到,main-content是<body>标签的class,页面中只有一个,所以应该用document.querySelector('.main-content')获取单个元素,而不是querySelectorAll。

修正后的JavaScript代码

const sections = document.querySelectorAll('.section');
const secBtns = document.querySelectorAll('.controls');
const secBtn = document.querySelectorAll('.control');
// 替换querySelectorAll为querySelector,获取单个元素
const allSections = document.querySelector('.main-content');

function PageTransitions(){
    // 用forEach替代for循环,更简洁
    secBtn.forEach(btn => {
        btn.addEventListener('click', function(){
            let currentBtn = document.querySelector('.active-btn');
            // 用classList操作替代字符串替换,更可靠
            currentBtn.classList.remove('active-btn');
            this.classList.add('active-btn');
        })
    });

    // 现在allSections是单个元素,可以正常绑定事件
    allSections.addEventListener('click', (e) =>{
        const id = e.target.dataset.id;
        if(id) {
            secBtns.forEach((btn) => {
                btn.classList.remove('active');
            });
            e.target.classList.add('active');
            sections.forEach((section)=>{
                section.classList.remove('active');
            });

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

PageTransitions();

额外优化说明

  1. 用querySelector替代querySelectorAll获取单个元素:当确定页面中只有一个匹配元素时,querySelector更高效,返回单个DOM元素,无需处理集合。
  2. 用classList操作类名:直接修改className容易覆盖原有类名,classList.add()、classList.remove()是更安全的方式。
  3. 用forEach替代for循环:遍历NodeList时,forEach代码更简洁易读,现代浏览器均支持。

内容的提问来源于stack exchange,提问作者codertrey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:27:29