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

连续调用AJAX函数后动态元素点击事件失效问题求助

问题:排序后点击产品元素无响应

我有两个AJAX函数:第一个用于对数据库中的数据进行排序(A-Z、Z-A等),第二个用于点击指定ID的.product元素后展示对应数据库数据。两个脚本单独运行时均正常,但先对元素列表进行排序后,再点击其中的.product元素却没有任何反应;未排序时点击能正常展示内容,排序后刷新页面再点击也能正常展示内容。

相关代码如下:

前端脚本

// head tag
<script>
$(function() {
  $('#sort_form').on('submit', function(e) {
    e.preventDefault();

    $.ajax({
      type: "post",
      url: 'php/display.php',
      data: new FormData(this),
      processData: false,
      contentType: false,
      success: function(response) {
        $(".recipe-list").html(response);
      },
      error: function() {
      }
    });
  });
});

$(function() {
  $('.product').on('click', function(e) {
    var product = $(this).attr('id');

    $.ajax({
      type: "post",
      url: 'php/recipe-container.php',
      data: {
        "name": product
      },
      success: function(response) {
        $(".display_recipe").html(response);
      }
    });
  });
});
</script>

HTML结构

<form method="POST" id="sort_form" enctype='multipart/form-data'>
  <input type="submit" id="sort_submit">
  <select name="sort" id="sort" onchange="$('#sort_submit').submit()">
    <optgroup label="Alphabetically">
      <option value="alphabet">A-Z</option>
      <option value="alphabet_rev">Z-A</option>
    </optgroup>
    <optgroup label="Whole">
      <option value="kcal_low_all">Kcal (to highest)</option>
      <option value="kcal_high_all">Kcal (to lowest)</option>
    </optgroup>
  </select>
</form>

<div class="recipe-list">
  <?php require "php/display.php"; ?>
</div>

<div class="display_recipe"></div>

后端核心代码(部分)

// display.php
function display_content($dish_type){
    require "sort-list.php";
    $con = mysqli_connect("localhost", "root", "", "cookbook");
    $res = mysqli_query($con,$sql);

    while($row = mysqli_fetch_assoc($res)) {
        $recipename = $row['name'];
        // ... 计算逻辑
        echo "<p id='".$recipename."' class='product'>".$recipename."</p>";
        // ... 输出其他信息
    }
    mysqli_close($con);
}
// ... 其他函数
// recipe-container.php
function display(){
    $con = mysqli_connect("localhost", "root", "", "cookbook");
    $product = $_POST["name"];
    $sql = "SELECT * FROM product WHERE name = '$product'";
    $res = mysqli_query($con,$sql);
    // ... 输出数据逻辑
}

原因分析

你当前的点击事件绑定方式$('.product').on('click', ...)只会给页面加载时已存在的DOM元素绑定事件。排序操作通过AJAX重新渲染了.recipe-list内的内容,新生成的.product元素是后续动态添加的,没有被绑定点击事件,因此点击无响应。

解决方案

使用事件委托(Event Delegation),将点击事件绑定到一个始终存在的父元素(比如.recipe-list)上,由父元素监听子元素的点击行为。这样无论子元素是初始加载还是动态生成的,都能触发事件。

修改后的前端脚本中,点击事件部分替换为:

$(function() {
  // 事件委托:绑定到父元素 .recipe-list
  $(".recipe-list").on('click', '.product', function(e) {
    var product = $(this).attr('id');

    $.ajax({
      type: "post",
      url: 'php/recipe-container.php',
      data: {
        "name": product
      },
      success: function(response) {
        $(".display_recipe").html(response);
      }
    });
  });
});

额外提示

你的PHP代码存在SQL注入风险,直接将用户输入(比如$_POST["name"]、$_POST["sort"])拼接到SQL语句中非常危险。建议使用MySQLi的预处理语句(Prepared Statements)来避免,示例如下:

修改recipe-container.php的查询逻辑:

function display(){
    $con = mysqli_connect("localhost", "root", "", "cookbook");
    $product = $_POST["name"];
    
    // 使用预处理语句
    $sql = "SELECT * FROM product WHERE name = ?";
    $stmt = mysqli_prepare($con, $sql);
    mysqli_stmt_bind_param($stmt, "s", $product);
    mysqli_stmt_execute($stmt);
    $res = mysqli_stmt_get_result($stmt);

    while($row = mysqli_fetch_assoc($res)) {
        // ... 输出数据逻辑
    }
    mysqli_stmt_close($stmt);
    mysqli_close($con);
}

修改sort-list.php的查询逻辑:

$sort = isset($_POST["sort"]) ? $_POST["sort"] : "alphabet_p";
// 先定义基础SQL,后续根据sort参数调整排序规则
$sql = "SELECT * FROM product WHERE type = ?";
$params = [$dish_type];
$paramType = "s";

$kcal_query = "(fat * 9 + carbohydrates * 4 + fiber * 2 + protein * 4)";

switch ($sort) {
    case "alphabet":
        $sql .= " ORDER BY name";
        break;
    case "alphabet_rev":
        $sql .= " ORDER BY name DESC";
        break;
    case "kcal_low_all":
        $sql .= " ORDER BY $kcal_query";
        break;
    case "kcal_high_all":
        $sql .= " ORDER BY $kcal_query DESC";
        break;
}

// 执行预处理语句(在display_content中执行)
// 在display_content中:
// $stmt = mysqli_prepare($con, $sql);
// mysqli_stmt_bind_param($stmt, $paramType, ...$params);
// mysqli_stmt_execute($stmt);
// $res = mysqli_stmt_get_result($stmt);

内容的提问来源于stack exchange,提问作者Astw41

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:39:21