【问题标题】:jQuery not recognizing dynamically-inserted DOM element?jQuery 无法识别动态插入的 DOM 元素?
【发布时间】:2014-03-17 23:47:15
【问题描述】:

又一个“基于所选父选项动态更改选择选项”的问题。

我的选择值动态变化 - 但在我的 rails 渲染子选择后 - 我失去了选择的样式(jQuery Chosen 插件)并且我无法对这个新注入的元素进行操作。

这里是代码现在的位置 - 它经历了几十次迭代 -

$('#vendor_block').on('change', '#vendor_name', function(){
      overlay.show();
      var v = $(this).val();
      vndr_json = {};
      vndr_json["v"] = v;
      $.ajax({
          type : "GET",
          url : "/purchaseorders/upd_vndr_locs",
          data : vndr_json,
          success: function(res) {
            overlay.hide();
            // console.log(typeof(res),res);
            jQuery("#vndrAddrOpts").html(res);
          }
      });
      $("#vendor_addresses").chosen(); // WHY DON'T YOU RENDER CHOSEN BOX?!
  });

我在我的页面上看到了这个新的选择框 - 我想在它发生变化时触发一个事件,但 DOM 已经加载,所以它没有“看到”我猜测的这个元素。

另外 - Chosen 插件不会在元素上呈现。不知道为什么 - 可能是同样的原因。

我正在使用 jQuery 的 .on(),就像 SO 上的每篇文章都说我应该使用的那样。但它不会“重新加载”此父项中的元素(并且 'vendor_block' 是 'vendor_name' 和 'vendor_addresses' 的父 div)。

您可以在此处看到选择框中的区别:

任何帮助都会很棒?

更新:

在 HTML 前后添加:

<div id="vndrAddrOpts">
    <select class="chzn-select vndrLocs span12" id="vendor_addresses" name="vendor_addresses"><option value="">Select Location</option></select>
</div>

这是原始的 HTML - 但是当 DOM 加载时,Chosen 会执行以下操作:

<div id="vendor_addresses_chzn" class="chzn-container chzn-container-single chzn-with-drop chzn-container-active" style="width: 100%; margin-bottom: 10px;" title=""><a href="javascript:void(0)" class="chzn-single" tabindex="-1"><span>Select Location</span><div><b></b></div></a><div class="chzn-drop"><div class="chzn-search"><input type="text" autocomplete="off"></div><ul class="chzn-results"><li id="vendor_addresses_chzn_o_0" class="active-result result-selected highlighted" style="">Select Location</li></ul></div></div>

这一切都很好 - 这是应该发生的。

这是注入选择框后的原始 HTML:

<div id="vndrAddrOpts">
    <select class="chzn-select vndrLocs span12" id="vendor_addresses" name="vendor_addresses"><option value="">Select Location</option></select>
</div>

这里是渲染的盒子 - 没有选择的东西。

<select class="chzn-select vndrLocs span12" id="vendor_addresses" name="vendor_addresses"><option value="">Select Location</option><option value="532757b4963e6505bc000003">Honolulu</option>
<option value="532768d0963e6505bc000004">Waipahu</option></select>

【问题讨论】:

    标签: javascript jquery html css ruby-on-rails


    【解决方案1】:

    我在这里找到了答案:

    Is there a way to dynamically ajax add elements through jquery chosen plugin?

    我实际上是在以一种过于复杂的方式解决这个问题 - 尝试注入和元素,而不是仅仅从元素开始并向其添加选项。

    我的 AJAX 现在看起来像这样:

           $.ajax({
              type : "GET",
              url : "/purchaseorders/upd_vndr_locs",
              data : vndr_json,
              success: function(res) {
                overlay.hide();
                var va = $('#vendor_addresses');
                // console.log(typeof(res),res);
                for (var i=0; i < res.length; i++) {
                  va.append(
                  $('<option></option>')
                    .val(res[i].id)
                    .html(res[i].name)
                  );  
                }
                va.trigger("liszt:updated");
                // jQuery("#vndrAddrOpts").html(res);
              }
            });
    

    因此,我们甚至不必担心从注入的元素重建所选元素 - 我们只需使用内置的“更新”触发器,它就可以很好地工作。

    【讨论】:

      【解决方案2】:

      您正在将 ajax 调用的结果插入到 DOM 中,它是成功回调,它在完成时执行(独立于脚本的执行)。在这种情况下,您的 ajax 请求正在发出,它开始执行之后的代码,然后是回调。在下一行代码之前调用成功回调的可能性很小,因为 ajax 调用是一个 http 请求,它需要比一行 JavaScript 执行更长的时间。

      你想把代码放在成功回调中,如:

            $.ajax({
                type : "GET",
                url : "/purchaseorders/upd_vndr_locs",
                data : vndr_json,
                success: function(res) {
                  overlay.hide();
                  $("#vndrAddrOpts").html(res);
                  $("#vendor_addresses").chosen();
                }
            });
      

      【讨论】:

      • 我将其作为我的第一次迭代进行了尝试 - 它不起作用。
      【解决方案3】:

      我认为所选方法在元素实际呈现在页面上之前触发,而 jQuery 找不到它。尝试将 $("#vendor_addresses").chosen(); 作为 AJAX 成功回调的一部分。如果做不到这一点,请尝试注释掉 selected() 方法,运行 AJAX 脚本,然后手动运行 selected() 方法。如果它那样工作,你必须稍微延迟一下。

      编辑:

      实际上,更仔细地查看您的代码,您似乎使用的是 ID 标签而不是类。多个 HTML 元素是否具有 #vendor_address id?如果是这样,请改用一个类,并使用$('.vendor_addresses').last().chosen();。如果你使用一个 ID,并使用一个 ID 选择器,jQuery 将选择第一个元素(如果找到具有该 ID),并停在那里。

      要吸取的教训?对 UNIQUE 元素使用 ID,对同一“类”的多个元素使用类。

      【讨论】:

      • 这是一个唯一的 ID - 问题是相关元素被注入页面取决于从第一个选择框中选择的内容。所以选择需要重新渲染。这是我遇到问题的重新渲染。
      • 你试过我的第一个补救措施了吗?延迟后手动运行命令?
      • 如果您可以在添加新选择框之前和之后发布表单的一些 HTML,那也会很有帮助。
      • 我添加了 HTML - 我已经尝试了你的补救措施(延迟后运行) - 它没有工作。
      猜你喜欢
      • 2011-01-15
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 2021-11-19
      • 2018-11-01
      相关资源
      最近更新 更多