首页 > 解决方案 > 使用 JavaScript addEventListener 到按钮

问题描述

在这段代码中,我使用了一个函数,该函数用 JSON 文件中的数据填充每个表行。我在表格的每一行附近添加了一个按钮。当我单击每个按钮时,我希望它执行一个功能(即使现在只是一个简单的警报)。这是我的代码:

function fillRow(employee){

var data = "";
var buttonCars = document.createElement("button");
var showCars = buttonCars.innerHTML = "show cars";

buttonCars.addEventListener("click", function() {
  alert('example alert');
});
        data =   "<tr>" + 
"<td>" + employee.name + "</td>" + 
"<td>" + employee.surname + "</td>" +
"<td>" + employee.email + "</td>" + 
"<td>" + "<button>" + showCars + "</button>" 
 + "</td>" + "</tr>";

return data;

}

现在,当我单击按钮时没有任何反应,我不明白为什么?

标签: javascripthtml-tabledom-eventsaddeventlistenerremoveeventlistener

解决方案


您正在向 中添加事件处理程序buttonCars,但没有将buttonCars页面放在任何地方;它在函数返回后无法生存。你的函数只返回一个 HTML 字符串(没有那个按钮),所以它不能通过它连接一个事件处理程序addEventListener(而且它可以的方式,onxyz-attribute-style 事件处理程序,通常是不好的做法)。

tr相反,让您的函数返回一个带有其行和按钮的实际元素:

function fillRow(employee){
    const tr = document.createElement("tr");
    tr.innerHTML = `
        <td>${employee.name}</td>
        <td>${employee.surname}</td>
        <td>${employee.email}</td>
        <td><button>show cars</button></td>`;
    tr.querySelector("button").addEventListener("click", function() {
        alert("example alert");
    });
    return tr;
}

请注意,这会改变您使用 from 的返回值的方式fillRow,因为它返回的是实际元素,而不是字符串。因此,您会将其附加到tbody元素(通常)而不是将其视为 HTML。

这是一个创建短表的示例:

function fillRow(employee){
    const tr = document.createElement("tr");
    tr.innerHTML = `
        <td>${employee.name}</td>
        <td>${employee.surname}</td>
        <td>${employee.email}</td>
        <td><button type="button">show cars</button></td>`;
    tr.querySelector("button").addEventListener("click", function() {
        alert("example alert");
    });
    return tr;
}

const employees = [
    {name: "Joe", surname: "Bloggs", email: "joe@example.com"},
    {name: "Muhammad", surname: "Abu-Yasein", email: "muhammad@example.com"},
    {name: "María", surname: "Gutierrez", email: "maría@example.com"},
];

const tbody = document.getElementById("table-body");

// Add the already-known employees
// (Generally best when doing lots of appends to use a document fragment
// or, in modern environments, the new `append` method that lets you
// provide multiple elements (https://developer.mozilla.org/en-US/docs/Web/API/Element/append),
// to avoid multiple distinct DOM modifications.)
tbody.append(...employees.map(fillRow));
/* Here's what it looks like with a fragment
const frag = document.createDocumentFragment();
for (const employee of employees) {
    frag.appendChild(fillRow(employee));
}
tbody.appendChild(frag); // Appends the fragment's children, not the fragment
*/

// Allow adding new ones
document.getElementById("btn-add").addEventListener("click", function() {
    const name = document.getElementById("new-name").value;
    const surname = document.getElementById("new-surname").value;
    const email = document.getElementById("new-email").value;
    const employee = {
        name, surname, email
    };
    employees.push(employee);
    tbody.appendChild(fillRow(employee));
});
label {
    display: grid;
    grid-template-columns: 1fr 2fr;
}
table {
    border: 1px solid black;
}
<table>
    <thead>
        <th>Name</th>
        <th>Surname</th>
        <th>email</th>
        <th></th>
    </thead>
    <tbody id="table-body"></tbody>
</table>
<hr>
<div>
    <label>
        Name:
        <input type="text" id="new-name">
    </label>
</div>
<div>
    <label>
        Surname:
        <input type="text" id="new-surname">
    </label>
</div>
<div>
    <label>
        Email:
        <input type="text" id="new-email">
    </label>
</div>
<input type="button" value="Add" id="btn-add">

(这在表单中使用了很多ids,我通常不会这样做,但是对于示例来说它既快速又简单。)


推荐阅读