同一页面上的两个 jQuery Ajax 调用,一个有效,另一个无效

Two jQuery Ajax calls on the same page, one works the other doesn't

我在同一个页面上有两个 Ajax 调用,第一个完美运行,所以我复制了它并更改了必要的值,因此它们是独立的,但是,第二个 Ajax 调用没有'不工作。我在一个单独的页面上测试过它,它工作正常,只有当两个调用都在同一页面上时它才不起作用,我是不是遗漏了什么?

jQuery('#lampbase').on('change', function(){
  var basevalue = $(this).val();
  jQuery.ajax({
    url: 'basesfetch.php',
    method: 'post',
    data: {basevalue1: basevalue},
    success: function(result){                    
      $("#baseresponse").html(result);
      $( "select" ).on('change',function() {
        var str = "";
        // For multiple choice
        $( "select option:selected" ).each(function() {
          str += $( this ).val() + " "; 
          console.log(str);
        });
      });

      jQuery('#lampbase').on('change', function(){
        $(".lampoptions").fadeIn();
      });
      
      jQuery("#lampcolor").change(function(e){
        var DefaultOption = $('option:selected', this).data('code');
        $("#detailcolor option[data-code='" + DefaultOption + "']").prop("selected", true);
        $("#lampholder option[data-code='" + DefaultOption + "']").prop("selected", true);
        $("#lampholder option[data-code='" + DefaultOption + "']").prop("selected", true);
        $("#FlexColour option[data-code='" + DefaultOption + "']").prop("selected", true);
        $("#Switch option[data-code='" + DefaultOption + "']").prop("selected", true);
      });
      
      $("select option").val(function(idx, val) {
        $(this).siblings("[value='"+ val +"']").hide();
      });          
    }
  });
});

jQuery('#lampshade').on('change', function(){
  var shadevalue = $(this).val();
  jQuery.ajax({
    url: 'shadefetch.php',
    method: 'post',
    data: {shadevalue1: shadevalue},
    success: function(result){                    
      $("#shaderesponse").html(result);
      $( "select" ).on('change',function() {
        var str = "";
        // For multiple choice
        $( "select option:selected" ).each(function() {
          str += $( this ).val() + " "; 
          console.log(str);
        });
      });
    }
  });
});

HTML代码:

<select id="lampbase">
  <option value="first">Select</option>
  <?php 
    $sql = mysqli_query($connection, "SELECT DISTINCT ProductName FROM TableLamps_CSV");
    while ($row = $sql->fetch_assoc()){
      $productname = $row['ProductName'];
      echo "<option value=\"$productname\">" . $row['ProductName'] . "</option>";
    }
  ?>
</select>

<select id="lampshade">
  <option value="first">Select</option>
  <?php 
    $sql = mysqli_query($connection, "SELECT DISTINCT ShapeName FROM shadetable");
    while ($row = $sql->fetch_assoc()){
      $shapename = $row['ShapeName'];
      echo "<option value=\"$shapename\">" . $row['ShapeName'] . "</option>";
    }
  ?>
</select>

代码中存在一些问题,其中一些您可能还没有遇到过。但是阻止您的第 2 个 AJAX 呼叫工作的方法非常简单:

问题 1:ID 重复

您在 SO 上共享的代码中未在此处显示,但我检查了您链接到的网站 (https://whiz.cz/ItQ),发现您有两个具有相同 ID 的元素 - lampshade.

我们正在查看 <select>

<select id="lampshade">

但是 div 上几层包含那个 select 也有相同的 ID:

<div class="container-fluid" ... id="lampshade">

IDs must be unique on the page. If you have duplicates, and use the ID as a jQuery selector, only the first one will match。在这种情况下,当 select 更改时您想要 运行 的 change 事件处理程序实际上绑定到 div,并且仅绑定到 divdivs 没有更改事件,因此永远不会触发。事件处理程序根本没有附加到 select

问题 2:嵌套事件处理程序

目前代码在其他事件处理程序中添加了事件处理程序。例如,在 #lampbase 更改处理程序中,您添加了一个 select 更改处理程序、另一个 #lampbase 更改处理程序和一个 #lampcolor 处理程序。问题是事件处理程序不会覆盖、更新或替换以前的处理程序。他们都只是堆叠起来,他们都保持活跃,他们都会运行。在这种特殊情况下,这意味着每次更改 #lampbase select 时,都会添加 3 个新的处理程序。

Here's a simple JSFiddle demo 显示像这样定义的事件处理程序如何叠加。

如果您返回并再次更改 #lampbase select,将在现有 4 个处理程序的基础上添加 3 个新处理程序,总共剩下 7 个,它们将 全部 运行 每次触发相关的 select 或。下次更改 #lampbase 时,原始更改处理程序 运行s,$(".lampoptions") 会淡出 3 次,并且代码会从 selected 选项构建 str 运行s 4 次。

在这种特殊情况下,只要您的用户不经常返回并更改 select,这可能不会导致任何严重问题。但是你可以想象这很容易变得非常混乱,你可能会开始注意到你的页面变得缓慢,因为所有这些重复的处理程序 运行.

最简单的解决方法是在任何可能 运行 重复的用户交互之外只定义一次处理程序。如果他们需要使用页面的当前状态 - 例如当前 selected 选项 - 让他们确定他们何时 运行 (而不是在流程中当状态是你的时候定义它们想要)。

请注意,当用户与页面交互时,也可以使用 .on().off() 动态地 add/remove 处理程序,但这里不需要额外的复杂性和代码。

小事 1:

无需为 #lampbase 添加单独的更改处理程序来执行淡入 - 您已经有该元素的更改处理程序,只需在其中执行即可。

小事 2:

如果您在其他事件处理程序之外定义同一个 select 处理程序,则无需定义两次。你实际上并没有对它生成的 str 做任何事情,但也许这是你接下来要做的事情:-)

小事 3:

这一行:

$("#lampholder option[data-code='" + DefaultOption + "']").prop("selected", true);

重复了,可能只是打错了。

这是应用了这些 suggestions/fixes 的代码:

jQuery('#lampbase').on('change', function () {

    var basevalue = $(this).val();

    jQuery.ajax({
        url: 'basesfetch.php',
        method: 'post',
        data: {
            basevalue1: basevalue
        },
        success: function (result) {
            $("#baseresponse").html(result);

            // No need for a separate handler to do this
            $(".lampoptions").fadeIn();

            // I am not sure what this is doing, but note it is running 
            // for every select on the page.
            $("select option").val(function (idx, val) {
                $(this).siblings("[value='" + val + "']").hide();
            });
        }
    });
});

jQuery('#lampshade').on('change', function () {

    var shadevalue = $(this).val();

    jQuery.ajax({
        url: 'shadefetch.php',
        method: 'post',
        data: {
            shadevalue1: shadevalue
        },
        success: function (result) {
            $("#shaderesponse").html(result);
        }
    });
});

jQuery("#lampcolor").change(function (e) {
    var DefaultOption = $('option:selected', this).data('code');
    $("#detailcolor option[data-code='" + DefaultOption + "']").prop("selected", true);
    $("#lampholder option[data-code='" + DefaultOption + "']").prop("selected", true);
    // Duplicated, typo?
    // $("#lampholder option[data-code='" + DefaultOption + "']").prop("selected", true);
    $("#FlexColour option[data-code='" + DefaultOption + "']").prop("selected", true);
    $("#Switch option[data-code='" + DefaultOption + "']").prop("selected", true);
});

// Only necessary to define this once, and outside any other handler
$("select").on('change', function () {
    var str = "";
    // For multiple choice
    $("select option:selected").each(function () {
        str += $(this).val() + " ";
        console.log(str);
    });
});