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

如何为列表项添加删除按钮以删除对应条目(纯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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:33:23