新手求助:API填充HTML表格后点击按钮无法获取电话与分机信息
问题描述
前端新手已通过fetch API获取数据并成功填充HTML表格,但点击每行的电话按钮时,无法将该行的TELEFONE(电话)和RAMAL(分机)信息通过弹窗展示,现有代码如下:
index.html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <script src="main.js"></script> <title>Document</title> </head> <body onload="apendeOnClick()"> <table id="tablerow"> <caption>Alien football stars</caption> <thead> <tr> <th>DATA</th> <th>TELEFONE</th> <th>RAMAL</th> <th>DESCRIÇÃO</th> <th>ACÕES</th> </tr> </thead> <tbody id="table_body"> </tbody> </table> <script> </script> </body> </html>
main.js代码
fetch("https://my-json-server.typicode.com/lfnoleto/api-fake/contact").then((data) => { return data.json() }).then((Objectdata) => { let tabelaData = "" Objectdata.map((values)=>{ tabelaData += `<tr> <td>${values.data}</td> <td>${values.tefone}</td> <td>${values.ramal}</td> <td>${values.descricao}</td> <td><button id="butao" class="btn btn-success" ><i class="fa fa-phone"></button></td> </tr>` }) document.getElementById("table_body").innerHTML = tabelaData innerHTML = tabelaData }) function apendeOnClick(){ const table = document.getElementById("tablerow") console.log(table) if (table) { for (var i = 0; i < table.rows.length; i++) { table.rows[i].childNodes[5].childNodes[1].onclick = function() { tableText(this); }; } } } function tableText(tableRow) { let telefone = tableRow.childNodes[1].innerHTML; let ramal = tableRow.childNodes[2].innerHTML; let obj = {'telefone': telefone, 'ramal': ramal}; console.log(obj); }
期望点击电话图标时,弹窗显示对应行的电话和分机信息。
解决方案
原代码存在异步时序、DOM索引不可靠、重复ID等问题,以下是修复后的完整代码及说明:
修复后的main.js代码
fetch("https://my-json-server.typicode.com/lfnoleto/api-fake/contact").then((data) => { return data.json() }).then((Objectdata) => { let tabelaData = "" Objectdata.map((values)=>{ // 移除重复ID,用class标识按钮;通过data属性存储对应行的电话和分机 tabelaData += `<tr> <td>${values.data}</td> <td>${values.tefone}</td> <td>${values.ramal}</td> <td>${values.descricao}</td> <td><button class="btn btn-success phone-btn" data-telefone="${values.tefone}" data-ramal="${values.ramal}"><i class="fa fa-phone"></i></button></td> </tr>` }) document.getElementById("table_body").innerHTML = tabelaData // 表格数据加载完成后再绑定按钮事件 bindPhoneButtonEvents() }) function bindPhoneButtonEvents() { // 获取所有电话按钮 const buttons = document.querySelectorAll('.phone-btn') buttons.forEach(btn => { btn.addEventListener('click', function() { // 从data属性中直接读取数据 const telefone = this.dataset.telefone const ramal = this.dataset.ramal // 弹窗展示信息 alert(`电话:${telefone}\n分机:${ramal}`) }) }) }
关键修改说明
- 异步时序修复:原代码在页面加载时就执行事件绑定,但fetch是异步操作,此时表格还未填充数据,导致事件绑定失效。修复后将事件绑定放在fetch成功回调中,确保表格数据加载完成后再绑定按钮。
- 移除重复ID:HTML中ID必须唯一,将按钮的重复ID改为class
phone-btn,方便批量选择元素。 - 数据存储优化:通过
data-telefone和data-ramal属性直接在按钮上存储对应行的电话和分机信息,避免依赖不可靠的DOM节点索引(容易因空格、换行等文本节点导致索引错误)。 - 事件绑定优化:使用
querySelectorAll批量获取按钮,通过addEventListener绑定点击事件,逻辑更清晰,兼容性更好。 - 弹窗实现:在点击事件中直接用
alert展示获取到的电话和分机信息,满足需求。
内容的提问来源于stack exchange,提问作者Lucas Noleto
相关产品推荐
相关产品推荐

