如何用jQuery为表格行按钮绑定事件,实现打印对应行id与name?
解决点击表格行按钮打印对应ID和Name的问题
嘿,我来帮你搞定这个问题~你的代码已经能生成表格行,但还缺少按钮的点击事件绑定,而且因为循环里用了var i,会有变量提升导致的闭包问题——等你点击按钮时,循环已经跑完,i的值会是数组的长度,这时候json[i]就取不到正确的数据啦。下面给你几种靠谱的解决方案:
方法1:使用事件委托(推荐)
这种方法不需要在循环里给每个按钮绑定事件,而是把事件绑定到父元素(比如table)上,利用事件冒泡来处理,性能更好,尤其适合动态生成的元素:
var json = [ { id: 1, name: "Jon", age: 20 }, { id: 2, name: "Jessy", age: 25 }, { id: 3, name: "Sarah", age: 30 }, ]; console.log(json); var tr; for (var i = 0; i < json.length; i++) { tr = $('<tr/>'); tr.append("<td>" + json[i].id + "</td>"); tr.append("<td>" + json[i].name + "</td>"); tr.append("<td>" + "<button class='btn btn-info'>Log</button>" + "</td>"); $('table').append(tr); } // 事件委托绑定点击事件 $('table').on('click', '.btn-info', function() { // 找到当前按钮所在的行 var $row = $(this).closest('tr'); // 获取行里的id和name var id = $row.find('td:first').text(); var name = $row.find('td:eq(1)').text(); console.log(`id: ${id} , name: ${name}`); });
方法2:循环里用let声明变量(ES6+)
如果你的环境支持ES6,可以把循环里的var i改成let i,这样每次循环都会创建一个独立的i变量,避免闭包问题,然后直接在循环里绑定点击事件:
var json = [ { id: 1, name: "Jon", age: 20 }, { id: 2, name: "Jessy", age: 25 }, { id: 3, name: "Sarah", age: 30 }, ]; console.log(json); var tr; // 把var改成let for (let i = 0; i < json.length; i++) { tr = $('<tr/>'); tr.append("<td>" + json[i].id + "</td>"); tr.append("<td>" + json[i].name + "</td>"); var $btn = $("<button class='btn btn-info'>Log</button>"); // 直接绑定点击事件 $btn.click(function() { console.log(`id: ${json[i].id} , name: ${json[i].name}`); }); tr.append($('<td/>').append($btn)); $('table').append(tr); }
方法3:利用闭包保存变量
如果环境不支持ES6,可以用立即执行函数(IIFE)创建闭包,把每次循环的i保存下来:
var json = [ { id: 1, name: "Jon", age: 20 }, { id: 2, name: "Jessy", age: 25 }, { id: 3, name: "Sarah", age: 30 }, ]; console.log(json); var tr; for (var i = 0; i < json.length; i++) { tr = $('<tr/>'); tr.append("<td>" + json[i].id + "</td>"); tr.append("<td>" + json[i].name + "</td>"); var $btn = $("<button class='btn btn-info'>Log</button>"); // 用IIFE保存当前的i值 (function(index) { $btn.click(function() { console.log(`id: ${json[index].id} , name: ${json[index].name}`); }); })(i); tr.append($('<td/>').append($btn)); $('table').append(tr); }
方法4:把数据存在按钮的data属性里
还可以把每行的id和name存在按钮的data属性中,点击时直接读取:
var json = [ { id: 1, name: "Jon", age: 20 }, { id: 2, name: "Jessy", age: 25 }, { id: 3, name: "Sarah", age: 30 }, ]; console.log(json); var tr; for (var i = 0; i < json.length; i++) { tr = $('<tr/>'); tr.append("<td>" + json[i].id + "</td>"); tr.append("<td>" + json[i].name + "</td>"); // 创建按钮时存入data属性 var $btn = $("<button class='btn btn-info' data-id='" + json[i].id + "' data-name='" + json[i].name + "'>Log</button>"); $btn.click(function() { var id = $(this).data('id'); var name = $(this).data('name'); console.log(`id: ${id} , name: ${name}`); }); tr.append($('<td/>').append($btn)); $('table').append(tr); }
这几种方法都能实现你要的效果,其中事件委托是最推荐的,因为它不需要给每个按钮单独绑定事件,代码更简洁,性能也更好~
内容的提问来源于stack exchange,提问作者TheTechGuy
相关产品推荐
相关产品推荐

