如何为列表项添加删除按钮以删除对应条目(纯JS实现)
原生JS实现表格条目的删除功能
针对你的需求,无需额外给条目添加ID,用原生JS可以通过两种简单方式实现删除按钮与对应条目的关联:
方法一:利用DOM层级关系匹配条目
在创建删除按钮时绑定点击事件,通过DOM层级关系找到当前按钮所在的表格行,提取条目的key值,再从数组中过滤掉对应条目后重新渲染页面。
修改你的newDetailTR函数,添加删除按钮的事件监听:
function newDetailTR(detail){ const $detailTR= document.createElement('tr'), $keyTD= document.createElement('td'), $categoryTD= document.createElement('td'), $amountTD= document.createElement('td'), $priceTD= document.createElement('td'), $totalPriceTD=document.createElement('td'), $deleteTD=document.createElement('button') $keyTD.textContent=detail.key $categoryTD.textContent=detail.category $amountTD.textContent=detail.amount $priceTD.textContent=detail.price $totalPriceTD.textContent = detail.totalPrice $deleteTD.textContent="Delete" // 添加按钮样式(可选) $deleteTD.className = 'btn btn-danger' // 绑定删除事件 $deleteTD.addEventListener('click', function() { // 找到当前按钮所在的表格行 const currentTR = this.closest('tr'); // 获取当前条目的key值 const targetKey = Number(currentTR.querySelector('td:first-child').textContent); // 从数组中过滤掉该条目 details = details.filter(item => item.key !== targetKey); // 重新渲染表格 render(); }) $detailTR.append($keyTD) $detailTR.append($categoryTD) $detailTR.append($amountTD) $detailTR.append($priceTD) $detailTR.append($totalPriceTD) $detailTR.append($deleteTD) return $detailTR; }
方法二:利用闭包直接关联条目对象
在创建按钮时,通过闭包直接捕获当前的detail对象,无需依赖DOM元素提取信息,逻辑更直接:
修改newDetailTR中的事件绑定部分:
// 绑定删除事件(闭包方式) $deleteTD.addEventListener('click', () => { // 直接过滤掉当前detail对象 details = details.filter(item => item !== detail); // 重新渲染表格 render(); })
完整修改后的JS代码
class Detail { constructor(key, category, amount, price) { this.key=key this.category=category this.amount=amount this.price=price } get totalPrice() { return (this.amount * this.price); } } // 把const改为let,允许修改数组内容 let details=[ new Detail(0,'Nails',300,4), new Detail(1,'Screws',400,6), new Detail(2,'Bolts',600,5), new Detail(3,'Self-tapping screw',700,3), new Detail(4,'Nails', 400, 2) ] const $detailsList = document.getElementById('details-list'), $detailsListTHALL = document.querySelectorAll('.detailsTable th') let column = 'key', columnDir = true function newDetailTR(detail){ const $detailTR= document.createElement('tr'), $keyTD= document.createElement('td'), $categoryTD= document.createElement('td'), $amountTD= document.createElement('td'), $priceTD= document.createElement('td'), $totalPriceTD=document.createElement('td'), $deleteTD=document.createElement('button') $keyTD.textContent=detail.key $categoryTD.textContent=detail.category $amountTD.textContent=detail.amount $priceTD.textContent=detail.price $totalPriceTD.textContent = detail.totalPrice $deleteTD.textContent="Delete" $deleteTD.className = 'btn btn-danger' // 方法二:闭包关联条目(推荐,逻辑更直接) $deleteTD.addEventListener('click', () => { details = details.filter(item => item !== detail); render(); }) // 方法一:DOM层级匹配(如果key可能重复,不推荐) /* $deleteTD.addEventListener('click', function() { const currentTR = this.closest('tr'); const targetKey = Number(currentTR.querySelector('td:first-child').textContent); details = details.filter(item => item.key !== targetKey); render(); }) */ $detailTR.append($keyTD) $detailTR.append($categoryTD) $detailTR.append($amountTD) $detailTR.append($priceTD) $detailTR.append($totalPriceTD) $detailTR.append($deleteTD) return $detailTR; } function getSortDetails(prop, dir) { const detailsCopy=[...details] return detailsCopy.sort(function(detailA, detailB){ if((!dir==false? detailA[prop] <detailB[prop] : detailA[prop] > detailB[prop])) return -1; }) } function render(){ let detailsCopy=[...details]; detailsCopy=getSortDetails(column, columnDir); $detailsList.innerHTML = ''; for(const detail of detailsCopy){ $detailsList.append(newDetailTR(detail)) } } $detailsListTHALL.forEach(elment => { elment.addEventListener('click', function() { column = this.dataset.column; columnDir = !columnDir; render() }) }) document.getElementById('add-detail').addEventListener('submit', function(event){ event.preventDefault() details.push(new Detail( Number(document.getElementById('input-key').value), document.getElementById('input-category').value, Number(document.getElementById('input-amount').value), Number(document.getElementById('input-price').value) )) render() alert('Item has been added!') event.target.reset(); }) render()
注意事项
- 方法一中如果存在
key重复的条目,会删除所有相同key的条目,因此如果你的key不是唯一标识,推荐使用方法二。 - 必须把
details数组从const改为let,否则无法修改数组内容。
内容的提问来源于stack exchange,提问作者lanamak
相关产品推荐
相关产品推荐

