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

如何删除Session Storage中动态增长音乐数组的指定单条项

Session Storage音乐列表单行删除功能实现方案

问题场景

我在Session Storage中存储了类似购物车结构、支持持续新增项的音乐列表数组,需要将其以表格形式展示:

  • 表格通过for循环逐行渲染,每行展示数组项的4个属性:Title、Artist、Album、Genre
  • 每行末尾配有Edit和Remove按钮
  • 核心需求:点击Remove按钮仅删除当前行对应的单条数组项,不能清空整个存储数组
    Session Storage中该数组的存储键为musicList,值结构示例如下:
[
  {title: "Rainbow", artist: "Jane", album: "SunnyBox", genre: "Melody"},
  {title: "Blue", artist: "Joe", album: "Azure Sea", genre: "Rock"},
  {title: "Gear", artist: "Romero", album: "Basset", genre: "Metal"},
  {title: "Amber", artist: "Amy", album: "Amy Coll", genre: "Soul pop"}
]

原有代码问题

原先编写的Remove按钮事件代码未生效,代码如下:

// 原有Remove按钮事件监听代码
button2.addEventListener("click", function(){
    let arrayOfMusic = JSON.parse(sessionStorage.getItem("musicList"));
    arrayOfMusic.splice([i], 1);
    sessionStorage.setItem('musicList',JSON.stringify(musicList));
})

代码失效的核心原因有4个:

  • 索引作用域异常:如果循环时用var声明索引变量i,事件回调触发时i会是循环结束后的最终值,无法匹配当前行对应的正确数组索引
  • splice参数写法错误:splice([i], 1)中将索引包裹在数组中属于无效传参,splice第一个参数需要直接传入数字类型的索引
  • 存储更新逻辑错误:splice操作是在arrayOfMusic变量上执行的,但存回Session Storage时序列化的是未更新的musicList变量,修改后的结果没有被存入存储
  • 缺少页面重渲染逻辑:即使存储更新成功,页面上已经渲染的旧表格行不会自动刷新,用户看不到删除效果

可直接运行的实现方案

推荐用事件委托+统一渲染函数的方式实现,不仅能解决索引错位问题,后续动态新增的音乐项也不需要重复绑定事件,代码可维护性更高:

// 统一表格渲染函数:页面首次加载、新增、删除、编辑操作后都调用该函数刷新视图
function renderMusicTable() {
  // 获取表格tbody容器,清空旧的渲染内容
  const tableTbody = document.querySelector('#musicTable tbody')
  tableTbody.innerHTML = ''
  // 从Session Storage读取最新的音乐列表,不存在时默认返回空数组避免报错
  const musicList = JSON.parse(sessionStorage.getItem('musicList')) || []

  // 循环生成每一行表格内容
  for (let i = 0; i < musicList.length; i++) {
    const currentItem = musicList[i]
    const tableRow = document.createElement('tr')
    // 填充属性列+操作按钮,给Remove按钮添加data-index自定义属性存当前行的数组索引
    tableRow.innerHTML = `
      <td>${currentItem.title}</td>
      <td>${currentItem.artist}</td>
      <td>${currentItem.album}</td>
      <td>${currentItem.genre}</td>
      <td>
        <button class="edit-btn">Edit</button>
        <button class="remove-btn" data-index="${i}">Remove</button>
      </td>
    `
    tableTbody.appendChild(tableRow)
  }
}

// 页面首次加载时渲染一次表格
renderMusicTable()

// 给tbody绑定统一的点击事件(事件委托),不用逐个给按钮绑定事件
document.querySelector('#musicTable tbody').addEventListener('click', function(e) {
  // 仅当点击的元素是Remove按钮时触发删除逻辑
  if (e.target.classList.contains('remove-btn')) {
    // 读取按钮上存的当前行对应的数组索引
    const deleteIndex = Number(e.target.dataset.index)
    // 读取最新的存储数组
    const latestMusicList = JSON.parse(sessionStorage.getItem('musicList')) || []
    // 删除对应索引的数组项
    latestMusicList.splice(deleteIndex, 1)
    // 将修改后的数组存回Session Storage
    sessionStorage.setItem('musicList', JSON.stringify(latestMusicList))
    // 重新渲染表格,同步页面展示
    renderMusicTable()
  }
})

方案说明

  • 用let声明循环索引,避免var的变量提升导致的索引值错乱问题
  • 通过data-index自定义属性将每行对应的数组索引直接绑定在DOM元素上,点击时直接读取,不会出现索引错位
  • 所有存储操作都基于读取到的最新数组执行,修改完成后直接将修改后的数组存回,避免变量名错误导致存储不更新
  • 抽离统一的渲染函数,每次数据变更后重新渲染表格,保证页面展示和存储数据完全一致
  • 事件委托的绑定方式对后续动态新增的表格行同样生效,不需要每次新增项后重新给按钮绑定事件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 16:33:26