You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在线电影库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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:22:06