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

JavaScript新手开发Todo List遇push函数TypeError问题求助

问题

我是刚学习JavaScript的新手,正在开发一个Todo List应用。点击添加按钮时,控制台报错:Uncaught TypeError: itemJsonArray.push is not a function。以下是我的代码:

JavaScript代码

add = document.getElementById("add");
add.addEventListener("click", () => {
console.log("Please wait a while...Updating List...")
tit = document.getElementById('title').value;
des = document.getElementById('descreption').value;
if (localStorage.getItem('name') == null) {
    itemJsonArray = []
    itemJsonArray.push([tit, des])
    localStorage.setItem('name', JSON.stringify(itemJsonArray))
}

else {
    itemJsonArrayStr = localStorage.getItem('name')
    itemJsonArray = JSON.parse(itemJsonArrayStr)
    itemJsonArray.push([tit, des]);
    localStorage.setItem('name', JSON.stringify(itemJsonArrayStr))
}

HTML代码

<div class="nav">
    <div class="float_nav">
        <li class="mt" type="none"><a href="#Home">Home</a></li>
        <li class="mt" type="none"><a href="#">Current Time</a></li>
        <li class="mt" type="none"><a href="#">Our Course</a></li>
        <li class="mt" type="none"><a href="#">Contact</a></li>
        <li class="purple" type="none"><button class="button button-to">
                <a class="black" href="#">Find Your List</a></button></li>
    </div>
</div>

<div class="form">
    <div>
        <h1 class="space">Todo List</h1>
        <label class="space">Title</label><br>
        <input id="title" class="space" required type="text" placeholder="Title"><br>
        <p>Write your title</p>
        <label id="margin-top">Descreption<br>
            <textarea id="descreption" name="textarea" cols="30" rows="3"></textarea>
        </label>
        <div class="check">
            <button type="submit" id="add" class="button-2 button-to">Add To List</button>
        </div>
    </div>
</div>

<div class="tb" id="todoContainer">
    <div class="td">
        <div class="tc"><p>No.</p></div>
        <div class="tc"><p>Title</p></div>
        <div class="tc"><p>Descreption</p></div>
        <div class="br tc"><p>Actions</p></div>
    </div>
    <div class="tr">
        <div class="tc"><p>1.</p></div>
        <div class="tc"><p>Title</p></div>
        <div class="tc"><p>Descreption</p></div>
        <div class="br tc"><button class="button-to">Delete</button></div>
    </div>
    <div class="tr">
        <div class="tc"><p>2.</p></div>
        <div class="tc"><p>Title</p></div>
        <div class="tc"><p>Descreption</p></div>
        <div class="br tc"><button class="button-to">Delete</button></div>
    </div>
</div>

<script src="Java.js"></script>

错误原因与修复

1. 核心错误:数据更新逻辑错误

在else分支中,修改数组后错误地将原字符串itemJsonArrayStr存入localStorage,而非更新后的数组itemJsonArray。这会导致:

  • localStorage中的数据从未真正更新
  • 若之前localStorage存入过非数组格式的name值,JSON.parse后得到的不是数组,调用push就会触发TypeError。

2. 次要问题:变量未声明

所有变量未用let/const声明,会成为全局变量,容易引发命名冲突。

3. 修复后的完整JavaScript代码

// 声明变量,避免全局污染
const addBtn = document.getElementById("add");
const titleInput = document.getElementById('title');
const descInput = document.getElementById('descreption');
const todoContainer = document.getElementById('todoContainer');

// 页面加载时渲染已有todo项
renderTodos();

addBtn.addEventListener("click", () => {
    const tit = titleInput.value.trim();
    const des = descInput.value.trim();

    // 空值判断,避免存入空项
    if (!tit) {
        alert('请输入Todo标题');
        return;
    }

    let itemJsonArray;
    const storedTodos = localStorage.getItem('todos'); // 改用语义化key

    if (!storedTodos) {
        itemJsonArray = [];
    } else {
        // 容错处理,确保解析后是数组
        try {
            itemJsonArray = JSON.parse(storedTodos);
            if (!Array.isArray(itemJsonArray)) {
                itemJsonArray = [];
            }
        } catch (e) {
            console.error('解析localStorage数据失败', e);
            itemJsonArray = [];
        }
    }

    // 用对象存储todo,结构更清晰
    itemJsonArray.push({ title: tit, description: des });
    localStorage.setItem('todos', JSON.stringify(itemJsonArray));

    // 清空输入框并重新渲染列表
    titleInput.value = '';
    descInput.value = '';
    renderTodos();
});

// 渲染todo列表到页面
function renderTodos() {
    // 保留表头,清空现有列表项
    const headerRow = todoContainer.querySelector('.td');
    todoContainer.innerHTML = '';
    todoContainer.appendChild(headerRow);

    const storedTodos = localStorage.getItem('todos');
    if (!storedTodos) return;

    let itemJsonArray;
    try {
        itemJsonArray = JSON.parse(storedTodos);
        if (!Array.isArray(itemJsonArray)) return;
    } catch (e) {
        console.error('解析数据失败', e);
        return;
    }

    // 动态生成todo项
    itemJsonArray.forEach((todo, index) => {
        const row = document.createElement('div');
        row.className = 'tr';

        row.innerHTML = `
            <div class="tc"><p>${index + 1}.</p></div>
            <div class="tc"><p>${todo.title}</p></div>
            <div class="tc"><p>${todo.description}</p></div>
            <div class="br tc">
                <button class="button-to" onclick="deleteTodo(${index})">Delete</button>
            </div>
        `;

        todoContainer.appendChild(row);
    });
}

// 删除todo项
function deleteTodo(index) {
    const storedTodos = localStorage.getItem('todos');
    if (!storedTodos) return;

    let itemJsonArray = JSON.parse(storedTodos);
    if (!Array.isArray(itemJsonArray)) return;

    itemJsonArray.splice(index, 1);
    localStorage.setItem('todos', JSON.stringify(itemJsonArray));
    renderTodos();
}

4. HTML调整说明

  • 给todo列表容器添加id="todoContainer",方便动态操作
  • 移除所有外部跳转链接,替换为无跳转占位
  • 修正label标签的闭合错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:15:32