如何使用jQuery获取点击按钮对应动态生成的隐藏input值
问题根因
- 循环生成房屋卡片时,给所有卡片内的表单、隐藏输入框、按钮都设置了相同的
id属性。HTML标准规定同一个页面中id必须全局唯一,用$("#hidden")这类id选择器查询元素时,永远只会返回页面上第一个匹配的元素,这就是每次都拿到第一个房屋ID的核心原因。 - 原有JS代码存在明显bug:重复绑定了两次封禁按钮的点击事件,
house_id变量没有被正确赋值就直接传给后端接口,还存在引号不配对、语法缺漏的错误。 - 元素查找没有限定范围:点击按钮时没有以当前按钮为起点查找所属卡片内的输入框,而是全局查找元素,自然匹配不到目标值。
- 原PHP代码还存在逻辑错误:角色判断两个分支都写了
$houses_array[$i]['role'] === 1,普通用户的判断条件写错;首次登录的文本逻辑写反,first_login为null应该是从未登录过。
修复方案
第一步:调整PHP循环输出的代码
去掉所有重复生成元素的重复id,保留class用于定位即可,修正原有的逻辑判断错误:
for ($i = 0; $i < count($houses_array); $i++) { // 修正原有逻辑判断错误 if ($houses_array[$i]['verify_status'] === 1) { $verify_text = "User is verified"; } else { $verify_text = "User is not verified"; } if ($houses_array[$i]['role'] === 1) { $role_text = "House admin"; } else { $role_text = "Regular user"; } if ($houses_array[$i]['first_login'] === null) { $first_login_text = "User has yet to login"; } else { $first_login_text = "User logged in for the first time"; } if ($houses_array[$i]['blocked'] === 1) { $blocked_text = "House is blocked"; } else { $blocked_text = "House is not blocked"; } // 去掉所有重复的id属性,仅保留class echo '<div class="card"> <div class="card-body"> <h5 class="card-title"><b>House name:</b> ' . $houses_array[$i]['household_name'] . '</h5> <form class="house-form"> <input type="hidden" class="house_id" value="' . $houses_array[$i]['household_id'] . '"> </form> <p class="card-text"><b>Blocked:</b> ' . $blocked_text . '</p> <button type="button" name="block_btn" class="btn btn-danger block">Block house</button> <button type="button" name="unblock_btn" class="btn btn-success unblock" style="margin-left: 20px">Unblock house</button> <br><br> <p class="card-text"><b>Users email:</b> ' . $houses_array[$i]['users_email'] . '</p> <p class="card-text"><b>Full name:</b> ' . $houses_array[$i]['full_name'] . '</p> <p class="card-text"><b>Verification status:</b> ' . $verify_text . '</p> <p class="card-text"><b>Users\'s role:</b> ' . $role_text . '</p> <p class="card-text"><b>Time of sign in:</b> ' . $houses_array[$i]['date_time_signup'] . '</p> <p class="card-text"><b>First login:</b> ' . $first_login_text . '</p> <p class="card-text"><b>Users\'s ip address:</b> ' . $houses_array[$i]['ip_adress'] . '</p> <p class="card-text"><b>Users\'s web browser and OS:</b> ' . $houses_array[$i]['web_browser_OS'] . '</p> </div> <div class="card-footer text-muted"> </div> </div>'; } ?>
优化点:把按钮的
type="submit"改成type="button",避免点击按钮触发默认的表单提交跳转行为。
第二步:重写jQuery点击逻辑
点击按钮时,先定位到当前按钮所属的卡片容器,再在容器范围内查找对应的隐藏输入框取值,不要全局查询元素,同时删掉重复绑定的事件、修正语法错误:
$(document).ready(function () { // 封禁按钮逻辑 $(".block").click(function () { // 以当前点击的按钮为起点,找到同级的house_id输入框取值 let house_id = $(this).siblings('form.house-form').find('.house_id').val(); $.ajax({ method: "post", url: "block_house.php", data: { house_id: house_id, action: 'block' }, success: function (response) { alert(response); window.location.reload(true); }, error: function () { alert("操作失败,请重试"); } }) }); // 解封按钮逻辑 $(".unblock").click(function () { let house_id = $(this).siblings('form.house-form').find('.house_id').val(); $.ajax({ method: "post", url: "block_house.php", data: { house_id: house_id, action: 'unblock' }, success: function (response) { alert(response); window.location.reload(true); }, error: function () { alert("操作失败,请重试"); } }) }); });
更简便的优化方案
如果不想逐层查找DOM元素,可以直接在输出按钮的时候把房屋ID存在按钮的data-*属性里,连隐藏表单都可以省略:
PHP部分直接把ID输出在按钮上:
<button type="button" class="btn btn-danger block" data-house-id="' . $houses_array[$i]['household_id'] . '">Block house</button> <button type="button" class="btn btn-success unblock" data-house-id="' . $houses_array[$i]['household_id'] . '" style="margin-left: 20px">Unblock house</button>
JS里直接拿data属性的值即可,不需要查找输入框:
let house_id = $(this).data('house-id');
这种方式代码更简洁,也不容易出现DOM查找错误的问题。
内容的提问来源于stack exchange,提问作者Janosz Крајишник
相关产品推荐
相关产品推荐

