jQuery无法识别动态插入的DOM元素?

时间:2014-03-17 23:47:15

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

另一个"根据所选的父选项动态更改选择选项"问题

我有选择值动态变化 - 但是在我的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已经加载了,所以它没有"看到"我猜这个元素。

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

我使用jQuery的.on()就像SO上的每个帖子都说的那样。但它并没有重新加载#34;此父级内的元素(以及' vendor_block'是' vendor_name'和' vendor_addresses')的父div。

您可以在此处的选择框中看到差异:

Chosen box (top) with non-Chosen box (bottom)

任何帮助都会很棒?

更新:

在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>

3 个答案:

答案 0 :(得分: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);
          }
        });

因此,我们只需使用内置的&#34;更新的&#34;而不是担心从注入的元素重建所选元素。触发器,效果很好。

答案 1 :(得分:0)

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

编辑:

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

要学习的课程?对UNIQUE元素使用ID,对同一&#39;类的多个元素使用类。

答案 2 :(得分:0)

您正在将您的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();
          }
      });