为何jQuery筛选函数无法对表格tbody与tr元素生效?
我仔细看了你的通讯录代码,搜索功能失效主要是几个细节问题搞的鬼,咱们一步步来搞定它:
1. 无效HTML结构导致DOM选择异常
你把搜索框<input id="myInput"直接塞在了<table>标签内部,这不符合HTML规范——<table>的直接子元素只能是<thead>、<tbody>、<tfoot>这类表格专属元素。浏览器会自动修正这种错误结构,间接导致你的搜索选择器找不到目标元素。
修复操作:把搜索框移到<table>外面:
<div class="container"> <header> <h1>Address Book</h1> <hr /> </header> <!-- 把搜索框挪到table上方 --> <input id="myInput" type="text" placeholder="Search.."> <br><br> <table id='table1' class="table"> <!-- 原table内容保持不变 --> </table> </div>
2. 表格行未插入到<tbody>中
你的build函数用table.prepend(...)把新行直接加到了<table>根节点下,而不是指定的<tbody>里。这就导致搜索代码里的$('tbody tr')根本找不到这些行——它们不在<tbody>范围内!
修复操作:把行插入到<tbody>中,同时注意不要给多个删除按钮用重复的id(ID必须唯一,改用类名绑定事件):
function build() { $tbody.html(''); var length = pplDetails.length; for (var i = 0; i < length; i++) { // 改为append到tbody,而非prepend到table $tbody.append('<tr><td><input type="text" value="' + pplDetails[i].firstName + '" ></td> <td><input type="text" value="' + pplDetails[i].lastName + '" ></td> <td><input type="text" value="' + pplDetails[i].phone + '" ></td> <td><input type="text" value="' + pplDetails[i].address + '" ></td> <td> <button class="btn btn-block remove-btn">Del</button></td></tr>'); } }
3. 删除功能的索引计算逻辑错误
你的delPerson函数里用table.find('td').index(element)获取行索引,这完全不对——element是<tr>元素,你却在所有<td>里找它的位置,肯定会得到错误的索引值。
修复操作:计算当前行在<tbody>中的正确索引,同时把事件绑定改成类选择器:
// 事件绑定改成类选择器 table.on('click', '.remove-btn', delPerson); // 删除函数修正 function delPerson(event) { var element = event.target.closest('tr'); // 获取当前tr在tbody中的索引 var i = $tbody.find('tr').index(element); pplDetails.splice(i, 1); build(); }
4. 重复引入jQuery导致冲突
你页面里引入了两次不同版本的jQuery,新版本会覆盖旧版本的实例,可能导致之前绑定的事件失效。
修复操作:删掉其中一个,建议保留新版本的jQuery:
<!-- 只保留这一个jQuery引入 --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="script.js"></script>
额外补充:搜索逻辑适配input内容
原来的搜索代码只取了<tr>的文本,但你的行里都是input输入框,<tr>本身没有文本内容。需要获取每个input的value来拼接搜索文本,才能正确匹配内容:
$(document).ready(function () { $("#myInput").on("keyup", function () { var value = $(this).val().toLowerCase(); $('tbody tr').filter(function () { // 提取当前行所有input的value并拼接 var rowText = $(this).find('input').map(function(){ return $(this).val().toLowerCase(); }).get().join(' '); $(this).toggle(rowText.indexOf(value) > -1) }); }); });
修复后的完整代码
HTML
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>repl.it</title> <link href="style.css" rel="stylesheet" type="text/css"> </head> <body> <div class="container"> <header> <h1>Address Book</h1> <hr /> </header> <input id="myInput" type="text" placeholder="Search.."> <br><br> <table id='table1' class="table"> <thead> <tr> <th>First Name</th> <th>Last Name</th> <th>Phone</th> <th>Address</th> <th>Action</th> </tr> </thead> <tbody> </tbody> <tfoot> <tr> <td> <input id='firstName' class='form-control' type="text" placeholder='Name'> </td> <td> <input id='lastName' class='form-control' type="text" placeholder='Surname'> </td> <td> <input id='phone' class='form-control' type="text" placeholder='Contact Number'> </td> <td> <input id='address' class='form-control' type="text" placeholder='Full Postal Address'> </td> <td> <div class="text-center"> <button id='add' class='btn btn-block'>Add</button> </div> </td> </tr> </tfoot> </table> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="script.js"></script> </body> </html>
JS
var adBook = (function () { // default fields for understanding var pplDetails = [{ firstName: 'Sam', lastName: 'Smith', phone: '004477995544', address: '33 jump st, London' }]; //variables declaration var table = $('#table1'); var $tbody = table.find('tbody'); var $firstName = table.find('#firstName'); var $lastName = table.find('#lastName'); var $phone = table.find('#phone'); var $address = table.find('#address'); var $button = table.find('#add'); //events calls $button.on('click', adPerson); table.on('click', '.remove-btn', delPerson); build(); //function to create new table data function build() { $tbody.html(''); var length = pplDetails.length; for (var i = 0; i < length; i++) { $tbody.append('<tr><td><input type="text" value="' + pplDetails[i].firstName + '" ></td> <td><input type="text" value="' + pplDetails[i].lastName + '" ></td> <td><input type="text" value="' + pplDetails[i].phone + '" ></td> <td><input type="text" value="' + pplDetails[i].address + '" ></td> <td> <button class="btn btn-block remove-btn">Del</button></td></tr>'); } } //function to add persons details function adPerson() { var data = { firstName: $firstName.val(), lastName: $lastName.val(), phone: $phone.val(), address: $address.val() }; pplDetails.push(data); // 清空所有输入框 $firstName.val(''); $lastName.val(''); $phone.val(''); $address.val(''); build() } //function to delete details function delPerson(event) { var element = event.target.closest('tr'); var i = $tbody.find('tr').index(element); pplDetails.splice(i, 1); build(); } return { adPerson: adPerson, delPerson: delPerson }; })(); //Search bar $(document).ready(function () { $("#myInput").on("keyup", function () { var value = $(this).val().toLowerCase(); $('tbody tr').filter(function () { var rowText = $(this).find('input').map(function(){ return $(this).val().toLowerCase(); }).get().join(' '); $(this).toggle(rowText.indexOf(value) > -1) }); }); });
这样修改后,搜索功能就能正常筛选通讯录内容,删除功能的逻辑也会正确执行啦。
内容的提问来源于stack exchange,提问作者JaseyJS

