jQuery change事件绑定疑问:两类写法为何一失效一this取值失败?
咱们逐个拆解你的疑问:
a) 为什么第一类change事件绑定无法生效?
第一种写法 $(document).on('change','select[name="id"]',function(){ alert('Not Working'); }); 是jQuery事件委托的标准用法,理论上完全可以正常工作。无法生效大概率是以下几个常见原因:
- 选择器匹配不到目标元素:仔细检查你的
<select>标签的name属性是不是严格等于id——注意大小写(比如name="Id"就匹配不到)、有没有多余的空格或者特殊字符(比如name=" id"或者name="id_"),这些都会导致选择器失效。 - 事件冒泡被阻止:如果页面上其他代码在处理这个
<select>的change事件时,调用了event.stopPropagation(),那事件就不会冒泡到document层级,委托的事件自然不会触发。 - 代码执行时机不对:如果这段代码写在页面
<head>里,又没有包裹在$(document).ready()或者$(function(){...})中,虽然事件委托绑定到了document,但如果后续动态生成的元素的name属性有问题,还是会触发失败(不过事件委托本身支持动态元素,所以这个概率较低)。
b) 第二类写法生效但$(this).val()无法取值,两类写法的差异
先明确两类写法的核心区别:
第一类写法(标准事件委托)
$(document).on('change','select[name="id"]',function(){ alert('Not Working'); });这是正确的事件委托用法:把事件绑定在
document这个顶层父元素上,当页面上的元素触发change事件并冒泡到document时,jQuery会检查触发事件的元素是否匹配第二个参数的选择器字符串select[name="id"],如果匹配就执行回调。此时回调里的this严格指向触发事件的那个<select>元素,$(this).val()可以正常获取选中值。第二类写法(错误用法)
$(document).on('change',$('select[name="id"]'),function(){ alert('Working'); // $(this).val() not working });这里的问题在于你误用了
on()方法的参数:jQuery的on()方法第二个参数只能是选择器字符串、数据对象或者null,不能直接传jQuery对象。当你传$('select[name="id"]')时,jQuery会把它转换成对应的DOM元素,然后直接把事件绑定到这些元素上(效果等同于$('select[name="id"]').on('change', function(){...})),根本不是事件委托。
至于$(this).val()取不到值,大概率是因为这种非标准的绑定方式导致this的指向混乱,不再指向触发事件的<select>元素,所以拿不到预期的值。
正确的写法建议
如果你的<select>是静态存在的(页面加载时就有),直接绑定事件即可:
$('select[name="id"]').on('change', function(){ alert('Working'); console.log($(this).val()); // 正常获取选中值 });
如果是动态生成的元素(后续通过JS添加到页面),就用标准的事件委托写法(也就是你的第一类写法,确保选择器正确即可):
$(document).on('change','select[name="id"]',function(){ alert('Working'); console.log($(this).val()); // 正常获取选中值 });
内容的提问来源于stack exchange,提问作者Piyush Ghevariya

