如果使用JavaScript动态添加了按钮,如何知道单击了哪个按钮?

时间:2019-01-17 09:45:47

标签: javascript html

我不知道如何解决该问题,如果有人知道如何解决该问题,请告诉我。如果需要,那么我将亲自发送代码以找出错误。

有两个容器:左和右。在左图中,我从中获取文本框和单选按钮(有效/无效)中的标题,描述和状态(有效/无效)的值。然后,在按下提交按钮后,每次单击提交按钮后,所有值都将填充到右容器表中,并带有编辑和删除按钮。我想删除单击删除按钮的特定行。但是我不知道如何在所有按钮中都使用onclick函数(doDelete())时访问该按钮。

function fillData() {
  var table = document.getElementById("myTable");
  var counter = table.querySelectorAll('tr').length;
  var key = counter;
  var row = table.insertRow(counter);
  row.id = "row-" + key;

  var titleCell = row.insertCell(0);
  var descCell = row.insertCell(1);
  var statusCell = row.insertCell(2);
  var actionCell = row.insertCell(3);

  var editButton = document.createElement("button");
  editButton.innerText = "Edit";
  editButton.id = "edit-" + key;
  editButton.setAttribute("onclick", "doEdit()");

  var delButton = document.createElement("button");
  delButton.innerText = "Delete";
  delButton.id = "delete-" + key;
  delButton.setAttribute("onclick", "doDelete()");

  titleCell.innerHTML = document.getElementById("panel-title").value;
  descCell.innerHTML = document.getElementById("panel-description").value;
  statusCell.innerHTML = (function () {
    var radios = document.getElementsByName("status");
    for (i = 0, len = radios.length; i < len; i++) {
      if (radios[i].checked) {
        return radios[i].value;
      }
    }
  }());

  actionCell.appendChild(editButton);
  actionCell.appendChild(delButton);

  var delBtnArr = document.querySelectorAll('input[type="button"]');
  console.log(delBtnArr);
}

实际结果:按删除按钮后,整个行将被删除。 预期结果:按下删除按钮后,将删除单击该按钮的特定行。

2 个答案:

答案 0 :(得分:0)

Javascript还发送关联的事件作为参数,这样您就可以通过使用事件实用程序来获取ID。您可以按如下方式获得单击的按钮ID。通过获取该ID,我认为您也可以获取关联的行。之后,您可以删除该行。

doDelete(event){
 let clickedButtonId = e.target.id;
 //get row id. I think you can get it.
 document.removeElement(rowId);
}

答案 1 :(得分:0)

Event Delegation

绑定/注册祖先事件

动态添加的标签无法绑定到事件处理程序/侦听器,只有页面加载后存在的标签才能绑定。因此,对于多个动态添加的标签(例如按钮),您必须找到一个祖先标签,它们全部共享,并将其绑定到您需要侦听的任何事件。对于您的按钮,它可以是最远的table的最祖先window *(推荐):

// On-event property. ALWAYS PASS THE EVENT OBJECT 
table.onclick = function(event) {...

OR

// Event Listener. Abbreviating the [Event Object][2] is OK, but you must be consistent.
table.addEventListener('click', function(e) {...

请勿使用事件属性 <button onclick="func()"...

技术上最接近的祖先是tbody,即使您没有将其添加到表中,浏览器也会默认将其添加。


使用Event.targetEvent.currentTarget属性

记住要传递事件对象,因为您需要它来...

  • ...使用event.target属性找到您实际单击的按钮。

  • ...获取具有event.currentTarget属性的表的引用。

  • ...可能防止诸如使用event.preventDefault()方法停止将表单提交到服务器之类的默认行为。

查看演示,它将具有事件处理程序的特定详细信息。


演示

演示中评论的详细信息

var table = document.querySelector("table");

document.forms[0].onsubmit = fillData;

/*
This onevent property handler has two functions note it is bound 
to the table NOT the buttons.
There's two conditionals and they only focus on classNames of 
either .del or .edit. Once it's determined if the clicked tag has
one of these classes then the appropriate function is called.
If neither class was clicked there's no opportunity for anything
else to act on the click because both conditionals end with 
return false thereby terminating the event handler.
*/
table.onclick = function(e) {
  if (e.target.className === 'del') {
    delRow(e);
    return false;
  }
  if (e.target.className === 'edit') {
    editRow(e);
    return false;
  }
};

function fillData(e) {
  var ui = e.target.elements;
  e.preventDefault();
  var idx = table.rows.length;
  var row = table.insertRow();
  row.id = 'r-' + idx;

  var cell1 = row.insertCell(0);
  var data1 = ui.title.value;
  cell1.textContent = data1;

  var cell2 = row.insertCell(1);
  var data2 = ui.desc.value;
  cell2.textContent = data2;

  var cell3 = row.insertCell(2);
  var data3 = ui.chk.checked ? 'Active' : 'Inactive';
  cell3.textContent = data3;

  var cell4 = row.insertCell(3);
  var btns = `
  <button class='edit'>&#128221;</button>
  <button class='del'>&#10060;</button>`;
  cell4.innerHTML = btns;
}

/*
Reference the .closest() row from clicked button
Get that row's id and split() it at the dash and pop() the number.
Then get a reference to the bound ancestor (table) and deleteRow() with the new number you just got.
*/
function delRow(e) {
  var row = e.target.closest('tr');
  var idx = row.id.split('-').pop();
  e.currentTarget.deleteRow(idx);
}

/*
Same as before get the index number from the closest row's id.
Reference the table and use the .rows property and number.
This reference will now allow you to use the .cells property.
Use the .cells property to toggle the contenteditable attribute
on the first three cells.
*/
function editRow(e) {
  var row = e.target.closest('tr');
  var idx = row.id.split('-').pop();
  var R = e.currentTarget.rows[idx];
  for (let c = 0; c < 3; c++) {
    var cell = R.cells[c];
    if (cell.hasAttribute('contenteditable')) {
      cell.removeAttribute('contenteditable');
    } else {
      cell.setAttribute('contenteditable', true);
    }
  }
}
body {
  font: 400 16px/25px Consolas;
  display: flex;
  justify-content: space-between;
}

fieldset {
  width: fit-content
}

input,
label,
textarea {
  font: inherit
}

input,
label,
button {
  display: inline-block;
  height: 25px;
}

#title {
  width: 27.5ch;
}

#chk {
  display: none;
}

#chk+label::after {
  content: '\2610';
  font-size: 20px;
  vertical-align: middle;
}

#chk:checked+label::after {
  content: '\2611';
}

[type='reset'] {
  margin-left: 5%
}

td {
  min-width: 60px;
  border-bottom: 1px solid #000;
  height: 25px;
}

tr td:last-child {
  border-bottom-color: transparent;
}

button {
  width: 35px;
  text-align: center;
}
<form id='data'>
  <fieldset>
    <legend>Enter Data</legend>
    <input id='title' type='text' placeholder='Title'><br>
    <textarea id='desc' rows='3' cols='25' placeholder='Description'></textarea><br>
    <input id='chk' type='checkbox'>
    <label for='chk'>Active </label>
    <input type='reset'>
    <input type='submit'>
  </fieldset>
</form>

<hr>

<table></table>