Jquery .change() 函数不适用于动态填充的 SELECT 列表

Posted

技术标签:

【中文标题】Jquery .change() 函数不适用于动态填充的 SELECT 列表【英文标题】:Jquery .change() function not working with dynamically populated SELECT list 【发布时间】:2011-01-03 03:52:00 【问题描述】:

我有一个使用 ajax 调用动态填充的选择字段,该调用仅返回所有 html 选择选项。这是 php 的一部分,它只是回显选择标签并动态填写每个选项/值。

echo "<select name='player1' class='affector'>";
echo "<option value='' selected>--".sizeof($start)." PLAYERS LOADED--</option>";

foreach ($start as $value) 
    echo "<option value='".$value."'>".$value."</option>";
   
  echo "</select>";
  

填充此列表后,我尝试调用更改事件,以便每当在 SELECT 列表或具有相同类的文本字段中更改默认选项时,它会禁用在另一部分中设置的单选按钮的形式。 (您可以看到我提出的让这部分功能正常工作的最初问题here)

$('.affector').change(function()
       $(this).parents('tr').find('input:radio').attr('disabled', false);
);

出于某种原因,即使我为选择字段提供了正确的类名(影响器),当我在该字段中选择不同的选项时,表单的其他部分也不会禁用。具有相同类的静态文本字段工作正常。我被难住了。

有什么想法吗?

【问题讨论】:

快速提示,而不是echo "&lt;option value='".$value."'&gt;",试试:echo "&lt;option value='$value'&gt;"。如果你正在访问一个数组,你可以这样做echo "&lt;option value='$values[0]'&gt;" 【参考方案1】:

刚刚评论了你的最后一个问题......这就是我所说的:

使用jQuery绑定

function addSelectChange() 
   $('select').bind('change', function() 
       // yada yada
   );
 

在您的 ajax 成功函数中调用 addSelectChange。它应该可以解决问题。也看一下 jQuery 实时事件(当您想在以后的项目中为所有当前和未来的 DOM 元素设置事件时)。不幸的是,live 还不支持更改事件和其他一些事件。绑定是下一个最好的事情

【讨论】:

【参考方案2】:

一个更新的答案..

由于元素是动态填充的,因此您正在寻找event delegation。

不过,不要使用.live()/.bind()/.delegate()。你应该使用.on()

根据jQuery API docs:

从 jQuery 1.7 开始,.on() 方法是将事件处理程序附加到文档的首选方法。对于早期版本,.bind() 方法用于将事件处理程序直接附加到元素。处理程序附加到 jQuery 对象中当前选定的元素,因此这些元素必须存在于调用 .bind() 的位置。更灵活的事件绑定见.on()事件委托的讨论。

因此你会使用这样的东西:

$(document).on('change', 'select', function (e) 
    /* ... */
);

【讨论】:

是的,适用于所有场景,静态或动态内容:)【参考方案3】:

一个使用 .live() 的例子

$('#my_form_id select[name^="my_select_name"]').live('change', (function () 
    console.log( $("option:selected", this).val());
    )
 );

【讨论】:

这个 .live() 总是对我有用,在动态填充的选择字段中。 .live() 现在已弃用。使用类似$(document).on("change",'#my_form_id select[name^="my_select_name"]', function() ... )【参考方案4】:

对于动态插入到 DOM 中的项目,它们的事件必须与

绑定
$('.selector').bind('change',function()  doWork() );

这是因为当您运行$(function()); 并使用$.click$.change 等绑定事件时,您将事件绑定到DOM 中已经存在的元素。之后您所做的任何操作都不会受到$(function()); 调用中发生的任何事情的影响。 $.bind 告诉您的页面在选择器中查找未来元素以及当前元素。

【讨论】:

.change 和 .bind 的工作方式相同。它们只会绑定到当前在 DOM 中的元素。 @anurag - 不正确。如果两个元素都已经在 DOM 中,是的,它们的工作方式相同。但是 .change 不会绑定 DOM 中的新元素(这就是 OP 提出问题的原因......), .bind 会将当前和未来的事件绑定到元素。 @Jason: 测试起来并不难.. 看看这个小的 html sn-p (slexy.org/raw/s2XA8QihVm) 我写信是为了测试bind 是否适用于未来的 dom 元素,但它不吨。这也是从jQuery的源代码中获取的,它基本上将change()mouseover()blur()等的函数调用转发给bind()。这是 jQuery 源代码中的一个小 sn-p 显示 - slexy.org/view/s206rDeFeO 或者您可以在 code.jQuery.com 本身上查看整个源代码 - code.jquery.com/jquery-latest.js。 live() 是绑定当前和未来事件的函数。【参考方案5】:

试试 .live: http://docs.jquery.com/Events/live

来自文档: 将处理程序绑定到所有当前和未来匹配元素的事件(如单击)。也可以绑定自定义事件。

【讨论】:

“当前不支持:...更改...”【参考方案6】:

我找到了只做的解决方案

<select id="myselect"></select> 

在 php/html 文件中,然后通过 ajax 为其生成选项:

$.post("options_generator.php", function (data)  $("#myselect").append(data); );

仅在 options_generator.php 中回显选项:

echo "<option value='1'>1</option>";
echo "<option value='2'>2</option>";

【讨论】:

【参考方案7】:

请改用 delegate() 函数。更多关于这里http://www.elijahmanor.com/differences-between-jquery-bind-vs-live-vs-delegate-vs-on/

【讨论】:

以上是关于Jquery .change() 函数不适用于动态填充的 SELECT 列表的主要内容,如果未能解决你的问题,请参考以下文章

jquery - $(this).remove() 不适用于 each() 函数

Angular4(更改)事件不适用于 jQuery select2?

jQuery .validate() 不适用于动态创建的表行

jquery mobile style不适用于常规选择

Jquery html不适用于动态添加的元素

Jquery 类选择器不适用于动态类选择器