如何删除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
相关产品推荐
相关产品推荐

