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

如何在Input值变更时更新LocalStorage中的待办任务数据?

待办清单LocalStorage同步更新问题解决方案

问题背景

开发集成LocalStorage的待办清单应用,已实现任务保存和页面刷新加载功能,但修改现有任务输入框的值时,无法正确同步更新LocalStorage中的对应数据——尝试用change事件时出现单个输入值替换整个任务数组的问题,每个任务输入元素已设置ID,需要正确实现修改同步。

现有代码

HTML代码

<!DOCTYPE html>
<html lang="fr">
    <head>
        <?php include 'layout/head.phtml'; ?>
    </head>

    <body>

    <header>
            <?php include 'layout/header.phtml'; ?>
    </header>

    <main>
        <div class="container">
            <div class="row">
                <div class="col-lg-12">
                    <!--Add list name h3-->
                    <h4>En cours</h4>
                    <div id="tasks-container">
                        
                    </div>
                    <div class="new-task-container-submit">
                        <form id="form-add-task" action="">
                            <input class="btn-style" type="submit" id="new-task-submit" value="+" title="Ajouter">
                            <input class="input-style" type="text" id="new-task-input" placeholder="Ajouter une tâche">
                        </form>
                    </div>
                    <div class="completed-tasks-container">
                        <h4>Terminées</h4>
                    </div>
                </div>
            </div>
        </div>
    </main>
    <footer>
        <?php include 'layout/footer.phtml'; ?>
    </footer>

    <script type="text/javascript" src="scripts/main.js"></script>
    </body>
</html>

JavaScript代码

let inputNewTask = document.querySelector("#new-task-input");
let tasksContainer = document.querySelector("#tasks-container");
let formAddTask = document.querySelector("#form-add-task");

let tasksList = [];
let tasksID = 1;

function genererTasks(){
    const listTasksJson = window.localStorage.getItem("Tasks name");
    const listTasks = JSON.parse(listTasksJson);

    for(let i = 0; i < listTasks.length; i++){
        
        let newTaskContainer = document.createElement("div");
        newTaskContainer.classList.add("new-task-container");
        let newTaskInput = document.createElement("input");
        newTaskInput.classList.add("input-style", "task-content");
        newTaskInput.id = "task-" + tasksID;
        tasksID = tasksID + 1;
        newTaskInput.type = "text";
        newTaskInput.value = listTasks[i];
        newTaskInput.textContent = listTasks[i].value;
        
        let iconDelete = document.createElement("i");
        iconDelete.classList.add("fa-regular", "fa-circle", "btn-style");

        tasksContainer.appendChild(newTaskContainer);
        newTaskContainer.appendChild(iconDelete);
        newTaskContainer.appendChild(newTaskInput);
        
        tasksList.push(listTasks[i]);
    }
}

//Generate the page
const listTasksJson = (localStorage.getItem("Tasks name") !== null);
if (listTasksJson){
    genererTasks();
}

//Listener add new task
formAddTask.addEventListener("submit", function(e){
    e.preventDefault();
    let taskContent = inputNewTask.value;
    if(!taskContent){
        alert("Veuillez remplir le champs");
    }else{
        
        inputNewTask.value = "";
        let newTaskContainer = document.createElement("div");
        newTaskContainer.classList.add("new-task-container");
        let newTaskInput = document.createElement("input");
        newTaskInput.classList.add("input-style" , "task-content");
        newTaskInput.id = "task-" + tasksID;
        tasksID = tasksID + 1;
        newTaskInput.type = "text";
        newTaskInput.value = taskContent;
        newTaskInput.textContent = taskContent.value;
        
        let iconDelete = document.createElement("i");
        iconDelete.classList.add("fa-regular", "fa-circle", "btn-style");

        tasksContainer.appendChild(newTaskContainer);
        newTaskContainer.appendChild(iconDelete);
        newTaskContainer.appendChild(newTaskInput);
        

        tasksList.push(taskContent);
        window.localStorage.setItem("Tasks name", JSON.stringify(tasksList));
    }
})

// Listener to change text tasks and put the new data in LocalStorage



//window.localStorage.removeItem("Tasks name");

解决方案

问题核心是当前tasksList存储的是纯字符串数组,无法通过输入框ID关联到具体任务项,导致修改时只能覆盖整个数组。需要调整数据结构为带唯一标识的对象数组,并通过事件委托实现动态任务的修改监听:

  1. 调整数据结构
    将任务从字符串改为包含id和content的对象,确保每个任务有唯一标识,方便后续定位修改。

  2. 修正任务生成逻辑
    在genererTasks函数中,给输入框添加data-task-id属性绑定任务ID,同时更新tasksList存储对象而非字符串:

    function genererTasks(){
        const listTasksJson = window.localStorage.getItem("Tasks name");
        const listTasks = JSON.parse(listTasksJson);
    
        // 更新tasksID为现有最大ID+1,避免重复
        tasksID = listTasks.length > 0 ? Math.max(...listTasks.map(t => t.id)) + 1 : 1;
    
        for(let i = 0; i < listTasks.length; i++){
            const task = listTasks[i];
            let newTaskContainer = document.createElement("div");
            newTaskContainer.classList.add("new-task-container");
            let newTaskInput = document.createElement("input");
            newTaskInput.classList.add("input-style", "task-content");
            newTaskInput.id = "task-" + task.id;
            // 绑定任务ID到输入框的dataset属性
            newTaskInput.dataset.taskId = task.id;
            newTaskInput.type = "text";
            newTaskInput.value = task.content;
            
            let iconDelete = document.createElement("i");
            iconDelete.classList.add("fa-regular", "fa-circle", "btn-style");
    
            tasksContainer.appendChild(newTaskContainer);
            newTaskContainer.appendChild(iconDelete);
            newTaskContainer.appendChild(newTaskInput);
            
            tasksList.push(task);
        }
    }
    
  3. 修正新增任务逻辑
    新增任务时存储对象而非字符串:

    formAddTask.addEventListener("submit", function(e){
        e.preventDefault();
        let taskContent = inputNewTask.value.trim();
        if(!taskContent){
            alert("Veuillez remplir le champs");
            return;
        }
        
        inputNewTask.value = "";
        const newTask = {
            id: tasksID,
            content: taskContent
        };
        
        let newTaskContainer = document.createElement("div");
        newTaskContainer.classList.add("new-task-container");
        let newTaskInput = document.createElement("input");
        newTaskInput.classList.add("input-style" , "task-content");
        newTaskInput.id = "task-" + tasksID;
        newTaskInput.dataset.taskId = tasksID;
        newTaskInput.type = "text";
        newTaskInput.value = taskContent;
        
        let iconDelete = document.createElement("i");
        iconDelete.classList.add("fa-regular", "fa-circle", "btn-style");
    
        tasksContainer.appendChild(newTaskContainer);
        newTaskContainer.appendChild(iconDelete);
        newTaskContainer.appendChild(newTaskInput);
        
        tasksList.push(newTask);
        window.localStorage.setItem("Tasks name", JSON.stringify(tasksList));
        tasksID++;
    })
    
  4. 添加修改同步的事件监听器
    使用事件委托监听tasksContainer内的输入框变化,找到对应任务并更新LocalStorage:

    // 监听任务输入框的修改事件
    tasksContainer.addEventListener("input", function(e){
        const target = e.target;
        // 判断触发事件的是任务输入框
        if(target.classList.contains("task-content")){
            const taskId = parseInt(target.dataset.taskId);
            const newContent = target.value.trim();
            
            // 找到tasksList中对应的任务
            const taskIndex = tasksList.findIndex(task => task.id === taskId);
            if(taskIndex !== -1){
                tasksList[taskIndex].content = newContent;
                // 同步到LocalStorage
                window.localStorage.setItem("Tasks name", JSON.stringify(tasksList));
            }
        }
    })
    
  5. 初始化逻辑修正
    初始化时如果LocalStorage有数据,正确解析对象数组:

    //Generate the page
    const storedTasks = localStorage.getItem("Tasks name");
    if (storedTasks){
        tasksList = JSON.parse(storedTasks);
        genererTasks();
    }
    

这样修改后,每个任务输入框的修改都会精准定位到tasksList中的对应对象,更新后同步到LocalStorage,不会再出现整个数组被替换的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:14:57