如何让jQuery点赞功能在类社交平台的每个帖子上正常生效?
解决仅首个帖子点赞功能生效的问题
问题根源
- 重复使用唯一ID:HTML规范中
id属性必须唯一,但你通过循环生成的每个帖子都用了id="likings"(点赞按钮)和id="like"(点赞数),jQuery的$("#likings")只会选中页面中第一个匹配的元素,导致后续帖子的按钮没有绑定点击事件。 - 目标元素定位错误:点击事件中
$("input").val()会直接取页面第一个input的值,$("#like").html(data)也只会更新第一个点赞数元素,无法对应到当前操作的帖子。 - SQL注入风险:
like.php中直接将POST参数拼入SQL语句,存在严重的安全隐患。
具体修改步骤
1. 修改index.php的HTML渲染部分
将重复的id改为class,确保每个帖子的元素可以被正确定位:
// 原点赞按钮部分 <i class="fa fa-thumbs-up" id="likings" aria-hidden="true" style="text-align: left; color: navy;"></i>like // 改为 <i class="fa fa-thumbs-up likings" aria-hidden="true" style="text-align: left; color: navy;"></i>like // 原点赞数部分 <span id="like">'.$count.'</span> // 改为 <span class="like-count">'.$count.'</span> // 原隐藏input部分 <input name="id" value="'.$id.'" hidden> // 改为(添加class方便定位) <input class="post-id" name="id" value="'.$id.'" hidden>
2. 修改jQuery点击事件代码
使用事件委托绑定动态生成元素的点击事件,并通过相对选择器定位当前帖子的元素:
$(document).ready(function(){ // 事件委托,绑定到document,监听所有.likings的点击 $(document).on('click', '.likings', function(){ // 获取当前点击按钮所在的帖子容器 var $post = $(this).closest('.post'); // 在当前帖子内获取对应的post id var postId = $post.find('.post-id').val(); $.post("like.php", { post_id: postId // 参数名改为更清晰的post_id }, function(data, status){ // 在当前帖子内更新点赞数 $post.find('.like-count').html(data); }); }); });
3. 修复like.php的SQL注入问题并优化逻辑
使用预处理语句防止注入,同时优化变量名和逻辑:
<?php include("conn.php"); // 检查参数是否存在 if(isset($_POST['post_id'])){ $postId = $_POST['post_id']; // 使用预处理语句插入点赞记录 $sql = "INSERT INTO likes(postid, likes) VALUES(?, 1)"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "i", $postId); mysqli_stmt_execute($stmt); // 统计当前帖子的点赞数 $countSql = "SELECT COUNT(*) FROM likes WHERE postid = ?"; $countStmt = mysqli_prepare($conn, $countSql); mysqli_stmt_bind_param($countStmt, "i", $postId); mysqli_stmt_execute($countStmt); mysqli_stmt_bind_result($countStmt, $count); mysqli_stmt_fetch($countStmt); echo $count; // 关闭语句连接 mysqli_stmt_close($stmt); mysqli_stmt_close($countStmt); } mysqli_close($conn); ?>
额外说明
- 事件委托的作用:因为帖子是通过PHP循环动态生成的,页面加载完成后才存在的元素无法直接用
$('.likings').click()绑定事件,事件委托可以解决这个问题。 - 相对选择器
closest()和find():确保操作的是当前点击帖子内的元素,不会影响其他帖子。
内容的提问来源于stack exchange,提问作者philipnation
相关产品推荐
相关产品推荐

