在线电影库Add to List按钮无刷新切换功能实现求助
问题说明
我正在开发一个在线电影库,现有无需页面刷新的「加入列表」按钮,功能正常但无法实现切换效果——需要支持无刷新添加/移除影片。目前通过if/else调用两个独立函数,自己JavaScript能力薄弱,参考示例修改后仍未成功,请求协助实现按钮切换功能。
(按钮状态示意图:显示已加入列表/未加入列表的切换按钮样式)
现有代码
主页面代码
<div id="content-new"> <?php $sql_action = "SELECT movies.img, movies.title, movies.title_full, movies.new, my_list.title, my_list.username FROM movies LEFT JOIN my_list ON movies.title_full = my_list.title WHERE new != '' ORDER BY movies.id DESC LIMIT 16"; $result_action = mysqli_query( $db_connect, $sql_action )or die( mysqli_error( $db_connect ) ); while ( $row_action = mysqli_fetch_assoc( $result_action ) ) { $img = $row_action[ 'img' ]; $title = $row_action[ 'title' ]; $title_full = $row_action[ 'title_full' ]; $new = $row_action [ 'new' ]; $mylist = $row_action[ 'username' ]; // 检查影片是否已存在于列表中 $stmt_count_fav = $db_connect->prepare("SELECT title FROM my_list WHERE title = ?"); $stmt_count_fav->bind_param("s", $title_full); $stmt_count_fav -> execute(); $stmt_count_fav -> store_result(); $stmt_count_fav -> fetch(); $count_fav = $stmt_count_fav->num_rows; $stmt_count_fav->close(); ?> <div id="div_fav_hover"> <form id="form-new" style="padding: 20px 0px 20px 0px;" method="post" action="movie.php"> <input id="btn_top" style="display: none" type="text" name="latest" id="latest" value="<?php if ($title_full == '') {echo $title;} else {echo $title_full;} ?>" /> <?php if ($mylist == $username) { ?> <input id="new_releases" type="image" name="image" src="images/<?php echo $img ?>"> <?php } else if ($count_fav <= 1) { ?> <input id="new_releases" type="image" name="image" src="images/<?php echo $img ?>"> <?php } ?> </form> <?php if ( $mylist == $username) { // 已在我的列表中 ?> <div class="div_new_delete"> <form id="form-new" class="class_new_delete"> <input style="display: none" type="text" name="title_home" value="<?php echo $title_full; ?>" /> <input style="display: none" name="favorite_delete_home" value="favorite_delete_home" /> <input id="btn_mylist_on_home" type="submit" name="btn_password" value="" class="class_fav_hover_on"> </form> </div> <?php } else if ($count_fav <= 1) { // 不在任何列表中 ?> <div class="div_new_add"> <form id="form-new" class="class_new_add"> <input style="display: none" type="text" name="title_home" value="<?php echo $title_full; ?>" /> <input style="display: none" name="favorite_home" value="favorite_home" /> <input id="btn_mylist_off_home" type="submit" name="btn_password" value="" class="class_fav_hover_off"> </form> </div> <?php } ?> </div> <?php } // 结束循环 ?> <script> $(function() { $('.class_new_add').on('submit', function(event) { event.preventDefault(); $.ajax({ type: 'POST', url: 'ajax/mylist.php', context:$(this), data: $(this).serialize(), success: function(data) { $(this).closest("div").html("<div class=\"div_new_delete\"><form id=\"form-new\" class=\"class_new_delete\"><input style=\"display: none\" type=\"text\" name=\"title_home\" value=\"<?php echo $title_full; ?>\" /><input style=\"display: none\" name=\"favorite_delete_home\" value=\"favorite_delete_home\" /><input id=\"btn_mylist_off_home\" type=\"submit\" name=\"btn_password\" value=\"\" class=\"class_fav_hover_on\"></form></div>") } }); }); }); $(function() { $('.class_new_delete').on('submit', function(event) { event.preventDefault(); $.ajax({ type: 'POST', url: 'ajax/mylist.php', context:$(this), data: $(this).serialize(), success: function(data) { $(this).closest("div").html("<div class=\"div_new_add\"><form id=\"form-new\" class=\"class_new_add\"><input style=\"display: none\" type=\"text\" name=\"title_home\" value=\"<?php echo $title_full; ?>\" /><input style=\"display: none\" name=\"favorite_home\" value=\"favorite_home\" /><input id=\"btn_mylist_on_home\" type=\"submit\" name=\"btn_password\" value=\"\" class=\"class_fav_hover_off\"></form></div>") } }); }); }); </script> </div>
ajax/mylist.php 代码
<?php include "../includes/db_connector.php"; ?> <?php if ( isset( $_POST[ 'favorite_home' ] )) { // 首页AJAX添加逻辑 $stmt_favorites = $db_connect->prepare("INSERT INTO my_list (title, username) VALUES (?, ?)"); $stmt_favorites->bind_param("ss", $title_home, $username); $title_home = $_POST['title_home']; $result=$stmt_favorites->execute(); $stmt_favorites->close(); } ?> <?php if ( isset( $_POST[ 'favorite_delete_home' ] )) { // 首页AJAX删除逻辑 $stmt_favorites = $db_connect->prepare("DELETE FROM my_list WHERE title = ? AND username = ?"); $stmt_favorites->bind_param("ss", $title_home, $username); $title_home = $_POST['title_home']; $result=$stmt_favorites->execute(); $stmt_favorites->close(); } ?>
更新后的输入字段代码
<?php if ( $mylist == $username) { // 已在我的列表中 ?> <form id="form-new" class="class_new_delete"> <input style="display: none" type="text" name="title_home" value="<?php echo $title_full; ?>" /> <input style="display: none" name="favorite_delete_home" value="favorite_delete_home" /> <input id="btn_mylist_on_home" type="submit" name="btn_mylist_on_home" value="" class="class_fav_hover_on"> </form> <?php } else if ($count_fav <= 1) { // 不在任何列表中 ?> <form id="form-new" class="class_new_add"> <input style="display: none" type="text" name="title_home" value="<?php echo $title_full; ?>" /> <input style="display: none" name="favorite_home" value="favorite_home" /> <input id="btn_mylist_off_home" type="submit" name="btn_mylist_off_home" value="" class="class_fav_hover_off"> </form> <?php } ?>
更新后的JavaScript代码
<script> $(function() { $(this).find('.class_new_add').on('submit', function(event) { event.preventDefault(); $.ajax({ type: 'POST', url: 'ajax/mylist.php', context:$(this), data: $(this).serialize(), success: function(data) { $(this).closest('.class_new_add').html("<input id=\"btn_mylist_off_home\" type=\"submit\" name=\"btn_password\" value=\"\" class=\"class_fav_hover_on\">") } }); }); }); $(function() { $(this).find('.class_new_delete').on('submit', function(event) { event.preventDefault(); $.ajax({ type: 'POST', url: 'ajax/mylist.php', context:$(this), data: $(this).serialize(), success: function(data) { $(this).closest('.class_new_delete').html("<input id=\"btn_mylist_on_home\" type=\"submit\" name=\"btn_password\" value=\"\" class=\"class_fav_hover_off\">") } }); }); }); </script>
解决方案
核心问题是动态生成的新按钮没有绑定事件,同时原代码存在几个逻辑漏洞:循环中重复使用相同ID导致选择器出错、AJAX替换HTML时PHP变量无法动态生效、事件绑定范围无法覆盖新生成元素。
修复步骤:
1. 修正PHP循环中的DOM结构
给每个影片操作容器添加唯一标识,移除重复ID:
<!-- 给容器添加唯一标识和存储影片标题的属性 --> <div class="div_fav_hover" data-title="<?php echo $title_full; ?>"> <!-- 移除重复的id="form-new",仅保留class --> <form class="form-movie-link" style="padding: 20px 0px 20px 0px;" method="post" action="movie.php"> <!-- 原有图片链接代码不变 --> <input id="btn_top" style="display: none" type="text" name="latest" value="<?php echo $title_full ?: $title; ?>" /> <input id="new_releases" type="image" name="image" src="images/<?php echo $img ?>"> </form> <?php if ( $mylist == $username) { // 已在我的列表中 ?> <div class="fav-action-container"> <form class="fav-form fav-delete"> <input style="display: none" type="text" name="title_home" value="<?php echo $title_full; ?>" /> <input style="display: none" name="action" value="delete" /> <input type="submit" value="" class="class_fav_hover_on"> </form> </div> <?php } else { // 不在我的列表中 ?> <div class="fav-action-container"> <form class="fav-form fav-add"> <input style="display: none" type="text" name="title_home" value="<?php echo $title_full; ?>" /> <input style="display: none" name="action" value="add" /> <input type="submit" value="" class="class_fav_hover_off"> </form> </div> <?php } ?> </div>
2. 简化AJAX后端逻辑(ajax/mylist.php)
统一用action参数区分添加/删除操作:
<?php include "../includes/db_connector.php"; // 校验必填参数 if (!isset($_POST['title_home'], $_POST['action'], $username)) { exit; } $title_home = $_POST['title_home']; if ($_POST['action'] === 'add') { // 添加到列表 $stmt = $db_connect->prepare("INSERT INTO my_list (title, username) VALUES (?, ?)"); $stmt->bind_param("ss", $title_home, $username); $stmt->execute(); } elseif ($_POST['action'] === 'delete') { // 从列表移除 $stmt = $db_connect->prepare("DELETE FROM my_list WHERE title = ? AND username = ?"); $stmt->bind_param("ss", $title_home, $username); $stmt->execute(); } $stmt->close(); ?>
3. 用事件委托修复JavaScript绑定问题
事件委托可让动态生成的元素正常触发事件:
<script> $(function() { // 绑定到父容器,处理所有动态生成的表单提交 $('#content-new').on('submit', '.fav-form', function(event) { event.preventDefault(); const $form = $(this); const $container = $form.closest('.fav-action-container'); const title = $form.find('[name="title_home"]').val(); const isAdd = $form.hasClass('fav-add'); $.ajax({ type: 'POST', url: 'ajax/mylist.php', data: $form.serialize(), success: function() { // 根据操作类型切换表单 if (isAdd) { $container.html(` <form class="fav-form fav-delete"> <input style="display: none" type="text" name="title_home" value="${title}" /> <input style="display: none" name="action" value="delete" /> <input type="submit" value="" class="class_fav_hover_on"> </form> `); } else { $container.html(` <form class="fav-form fav-add"> <input style="display: none" type="text" name="title_home" value="${title}" /> <input style="display: none" name="action" value="add" /> <input type="submit" value="" class="class_fav_hover_off"> </form> `); } } }); }); }); </script>
关键改进点:
- 使用事件委托绑定事件,确保动态生成的按钮能触发AJAX
- 移除重复DOM ID,避免选择器冲突
- 统一AJAX接口参数,简化后端逻辑
- 用JavaScript存储影片标题,避免PHP变量在动态内容中失效
内容的提问来源于stack exchange,提问作者colemaniac
相关产品推荐
相关产品推荐

