Jquery .change()函数在动态填充的SELECT列表中不起作用

26

我有一个选择字段,通过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>";
}  

在填充完这个列表之后,我尝试调用一个更改事件,以便每当选择列表中的默认选项或具有相同类的文本字段更改时,它都会禁用表单中另一部分中的一个单选按钮集。 (您可以在此处看到我提出的初始问题,以使此功能工作)
$('.affector').change(function(){
       $(this).parents('tr').find('input:radio').attr('disabled', false);
});

由于某些原因,即使我给选择字段正确的类名(affector),当我选择不同的选项时,表单的其他部分仍然没有被禁用。具有相同类的静态文本字段正常工作。我被难住了。
有任何想法吗?

3
快速技巧:代替使用 echo "<option value='".$value."'>",建议使用 echo "<option value='$value'>"。如果你要访问一个数组,可以尝试使用 echo "<option value='{$values[0]}'>" - Skilldrick
7个回答

20

刚刚在你最后一个问题上发表了评论... 这是我的意见:

使用jQuery bind

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

在你的ajax成功函数中调用addSelectChange。它应该解决问题。也可以看一下jQuery live事件(当你想为所有当前和未来的DOM元素设置事件时,在以后的项目或其他内容中使用)。不幸的是,change事件和一些其他事件尚未得到live支持。Bind是下一个最好的选择。


9

更多最新答案..

由于元素是动态生成的,您需要使用事件委派

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

根据jQuery API文档:

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

因此,您可以使用类似以下的代码:

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

1
是的,这适用于所有场景,静态或动态内容 :) - user889030

5
使用 .live() 的示例
$('#my_form_id select[name^="my_select_name"]').live('change', (function () {
    console.log( $("option:selected", this).val());
    })
 );

1
这个 .live() 对于我来说总是有效的,特别是在动态生成的选择字段中。 - arslaan ejaz
3
.live()现已弃用。请使用类似以下的代码: $(document).on("change",'#my_form_id select[name^="my_select_name"]', function() { ... }) 来代替。注意不要改变原有的意思,并尽可能使翻译通俗易懂。 - Seybsen

3
对于动态插入到DOM中的项,它们的事件必须使用绑定方式来处理。
$('.selector').bind('change',function() { doWork() });

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

.change和.bind的工作方式相同。它们只会绑定到当前在DOM中的元素。 - Anurag
@anurag - 不正确。如果两个元素已经在DOM中,它们的工作方式是相同的。但是.change不会绑定DOM中的新元素(这就是OP提出问题的原因...),.bind将为当前和未来的事件绑定元素。 - Jason
@Jason:测试并不难,可以看一下我写的这个小的HTML片段(http://slexy.org/raw/s2XA8QihVm),来测试`bind`是否适用于未来的DOM元素,但事实上它并不适用。此外,这是从jQuery的源代码中提取的,它基本上将`change()`、`mouseover()`、`blur()`等函数调用转发到`bind()`。以下是jQuery源代码的一个小片段,显示了这一点 - http://slexy.org/view/s206rDeFeO 或者你可以在code.jQuery.com上查看整个源代码 - http://code.jquery.com/jquery-latest.js。而`live()`则是绑定当前和未来事件的函数。 - Anurag

1

我找到了一个解决方案,只需

<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>";

1

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

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


目前不支持:更改... - Sampson

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接