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

不使用Cookie实现TodoList持久化及多设备同步技术咨询

解决TodoList持久化与多设备同步问题

为什么直接修改HTML文件不可行

浏览器中的JavaScript出于安全限制,没有权限直接修改本地的HTML文件。你用appendChild操作的只是内存中的DOM树,刷新页面后浏览器会重新加载原始HTML文件,所以临时添加的内容会消失。

方案1:单设备持久化(无需后端,用localStorage)

localStorage是浏览器提供的本地存储API,不属于Cookie,能将数据持久化存储在用户设备上,刷新页面后不会丢失。修改你的代码如下:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Practice </title>
  <link href="style.css" rel="stylesheet" type="text/css" />
</head>

<body>
  <input id="todo-title" type="text" />
  <input id="date-picker" type="date" />
  <button onclick="addTodo();">Add Todo</button>
  
  <div id="todo-list"></div>
  
  <script>
    // 从localStorage读取已保存的todos,没有则用默认数组
    let todos = JSON.parse(localStorage.getItem('todos')) || [{
      title: 'Get groceries',
      dueDate: '2021-10-04'
    }, {
      title: 'Wash car',
      dueDate: '2021-02-03'
    }, {
      title: 'Make dinner',
      dueDate: '2021-03-04'
    }];

    render();
    
    function addTodo(){
      const textbox = document.getElementById('todo-title');
      const title = textbox.value.trim();
      const datePicker = document.getElementById('date-picker');
      const dueDate = datePicker.value;
      
      if (title && dueDate) { // 简单校验输入
        todos.push({
          title: title,
          dueDate: dueDate
        });
        // 保存到localStorage
        localStorage.setItem('todos', JSON.stringify(todos));
        render();
        // 清空输入框
        textbox.value = '';
        datePicker.value = '';
      }
    }
    
    function render(){
      const todoList = document.getElementById('todo-list');
      todoList.innerHTML = '';
      
      todos.forEach(function(todo){
        const element = document.createElement('div');
        element.innerText = `${todo.title} is due by ${todo.dueDate}`;
        todoList.appendChild(element);
      });
    }
  </script>
  
  <script src="script.js"></script>
</body>
</html>

关键修改点:

  • 把todos从const改成let,支持后续更新
  • 初始化时从localStorage读取数据,解析为JSON对象;无数据则用默认数组
  • 每次添加Todo后,用JSON.stringify把数组转成字符串,存入localStorage

方案2:多设备同步(需要后端服务)

localStorage仅能在单个设备存储数据,要实现多设备同步,必须借助后端服务存储和同步数据。这里推荐用Firebase实时数据库(无需自行搭建服务器),步骤如下:

  1. 注册Firebase账号,创建新项目,启用Realtime Database,测试阶段可设置公开规则(生产环境需配置权限):
    {
      "rules": {
        ".read": true,
        ".write": true
      }
    }
    
  2. 为项目添加Web应用,获取Firebase配置代码
  3. 修改TodoList代码接入Firebase:
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Practice </title>
  <link href="style.css" rel="stylesheet" type="text/css" />
  <!-- 引入Firebase SDK -->
  <script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-database.js"></script>
</head>

<body>
  <input id="todo-title" type="text" />
  <input id="date-picker" type="date" />
  <button onclick="addTodo();">Add Todo</button>
  
  <div id="todo-list"></div>
  
  <script>
    // 替换成你的Firebase配置
    const firebaseConfig = {
      apiKey: "YOUR_API_KEY",
      authDomain: "YOUR_AUTH_DOMAIN",
      databaseURL: "YOUR_DATABASE_URL",
      projectId: "YOUR_PROJECT_ID",
      storageBucket: "YOUR_STORAGE_BUCKET",
      messagingSenderId: "YOUR_SENDER_ID",
      appId: "YOUR_APP_ID"
    };

    // 初始化Firebase
    firebase.initializeApp(firebaseConfig);
    const db = firebase.database().ref('todos');
    
    // 监听数据库变化,自动更新页面
    db.on('value', (snapshot) => {
      const todos = snapshot.val() || [];
      render(todos);
    });
    
    function addTodo(){
      const textbox = document.getElementById('todo-title');
      const title = textbox.value.trim();
      const datePicker = document.getElementById('date-picker');
      const dueDate = datePicker.value;
      
      if (title && dueDate) {
        // 向数据库添加新Todo
        db.push({
          title: title,
          dueDate: dueDate
        });
        // 清空输入框
        textbox.value = '';
        datePicker.value = '';
      }
    }
    
    function render(todos){
      const todoList = document.getElementById('todo-list');
      todoList.innerHTML = '';
      
      Object.values(todos).forEach(function(todo){
        const element = document.createElement('div');
        element.innerText = `${todo.title} is due by ${todo.dueDate}`;
        todoList.appendChild(element);
      });
    }
  </script>
  
  <script src="script.js"></script>
</body>
</html>

说明:

  • Firebase实时数据库会自动同步所有设备的数据,任何设备添加/修改Todo,其他设备都会实时更新
  • 生产环境需配置Firebase身份验证规则,防止未授权访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:55:50