簡體   English   中英

使用 JavaScript 將事件偵聽器添加到按鈕

[英]addEventListener to button with JavaScript

在這段代碼中,我使用了一個函數,該函數用來自 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;

}

現在,當我單擊按鈕時什么也沒有發生,我不明白為什么?

您正在向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;
}

請注意,這會改變您使用fillRow返回值的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">

(這在表單中使用了很多id ,我通常不會這樣做,但對於示例來說它既快速又簡單。)

我可以建議兩種不混合 HTML 和 JavaScript 代碼的方法嗎?

方法 1:即席代碼

一種相對簡單的方法,其中函數與您要填充的特定表緊密綁定

 function addCell(data) { const tdElem = document.createElement('td'); if (data instanceof HTMLElement) { tdElem.append(data); } else { tdElem.innerText = data } return tdElem; } function handleCarBtnClick(employeeId) { window.alert(`${employeeId}'s car`) } function fillEmployeeRow(employeeData) { const trElem = document.createElement('tr'); const btnCarElem = document.createElement('button'); btnCarElem.innerText = 'show cars'; btnCarElem.addEventListener('click', () => handleCarBtnClick(employeeData.name)); trElem.append(addCell(employeeData.name)); trElem.append(addCell(employeeData.surname)); trElem.append(addCell(employeeData.email)); trElem.append(addCell(btnCarElem)); document.querySelector('#employees-table').append(trElem); } // Populating the employees table [{ name: 'John', surname: 'Doe', email: 'john.doe@email.tld' }, { name: 'Jane', surname: 'Doe', email: 'jane.doe@email.tld' }, { name: 'Foo', surname: 'Bar', email: 'foo.bar@email.tld' } ].forEach(employee => fillEmployeeRow(employee))
 <table id='employees-table'> <tr> <th>Name</th> <th>Surname</th> <th>E-mail</th> <th>Cars</th> </tr> </table>

方法二:可重用的泛型函數

我承認這對於這樣一個簡單的案例來說可能有點矯枉過正,但是,只是為了好玩和為了促進良好的(?)實踐......

 // Reusable functions function addCell(data) { const tdElem = document.createElement('td'); if (data instanceof HTMLElement) { tdElem.append(data); } else { tdElem.innerText = data } return tdElem; } function addRow(data, fields, targetTable) { const trElem = document.createElement('tr'); fields.forEach(field => trElem.append(addCell(data[field]))); targetTable.append(trElem); } function addButton(btnText, btnClickHandler) { const btnElem = document.createElement('button'); btnElem.innerText = btnText; btnElem.addEventListener('click', btnClickHandler); return btnElem; } // Populating the two tables using the same functions // Employees table function handleCarBtnClick(employeeId) { window.alert(`${employeeId}'s car`) } [{ name: 'John', surname: 'Doe', email: 'john.doe@email.tld', salary: 30000 }, { name: 'Jane', surname: 'Doe', email: 'jane.doe@email.tld', salary: 30000 }, { name: 'Foo', surname: 'Bar', email: 'foo.bar@email.tld', salary: 30000 } ].forEach(employee => { const args = { data: { ...employee, btn: addButton('show cars', () => handleCarBtnClick(employee.name)) }, fields: ['name', 'surname', 'email', 'btn'], targetTable: document.querySelector('#employees-table') }; addRow(args.data, args.fields, args.targetTable) }); // Departments table [{ name: 'Sales', location: '2nd floor, Building A', phone: '123456789' }, { name: 'Marketing', location: '2nd floor, Building A', phone: '123456789' }, { name: 'Human Resources', location: '1st floor, Building A', phone: '123456789' } ].forEach(department => { addRow(department, ['name', 'location'], document.querySelector('#departments-table')); });
 <table id='employees-table'> <tr> <th>Name</th> <th>Surname</th> <th>E-mail</th> <th>Cars</th> </tr> </table> <hr /> <table id='departments-table'> <tr> <th>Name</th> <th>Location</th> </tr> </table>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM