jQuery两种select元素change事件绑定方式的差异咨询
两种jQuery事件绑定写法的实质差异
两种写法运行效果一致只是特定场景下的巧合,二者存在多维度的实质区别:
- 动态元素支持能力完全不同
选项A是事件委托实现:事件实际绑定在长期存在的document根节点上,只要页面上触发的change事件冒泡到根节点,jQuery就会校验事件源是否匹配#selectAAA/#selectBBB选择器,匹配就执行回调。哪怕这两个下拉框是绑定动作执行后才动态插入页面的(比如Ajax异步渲染返回、JS动态append生成、弹窗内动态渲染的表单项),事件依然能正常触发。
选项B是直接绑定实现:仅在DOM ready节点查找当前页面已经存在的对应id元素,把回调直接绑定在找到的DOM节点上。如果两个下拉框是绑定完成后才动态加入页面的,或者元素被删除后重新插入过,之前绑定的事件会直接失效,无法触发。 - 性能开销不同
选项A的委托机制会让所有冒泡到document的change事件都触发一次选择器匹配校验,页面DOM结构复杂、change类事件触发频繁时,会产生不必要的性能消耗。
选项B的直接绑定没有额外的选择器匹配开销,事件触发时直接执行对应回调,静态元素场景下性能更优。 - 触发逻辑和冒泡依赖不同
选项A的回调要等事件冒泡到document节点才会执行,如果两个下拉框的任意父级节点在冒泡流程中调用了event.stopPropagation()阻止冒泡,回调就不会执行。
选项B的回调在事件到达元素本身的目标阶段就会执行,只要事件能到达对应元素,哪怕后续冒泡流程被阻断也不影响回调触发。 - 代码编写容错性不同
选项A的代码不需要等DOM加载完成,哪怕写在页面head标签里、对应元素还没渲染,也不会报错,后续元素渲染完成后事件自然生效。
选项B的直接绑定必须等目标元素渲染完成后才能执行,你贴的选项B代码正是因为包裹在$(document).ready()里,才保证了绑定动作在DOM就绪后执行;如果去掉ready包裹、代码写在元素前面,会因为找不到元素导致绑定失败。另外你贴的选项B代码存在语法错误,回调函数末尾少了闭合的),正确写法收尾应该是});。
代码统一规范建议
- 对于页面初始渲染就存在的静态元素,优先使用选项B的直接绑定写法,性能更高、逻辑更直观。
- 对于动态生成的元素,使用事件委托写法时尽量不要把事件绑在
document上,应该绑定在离目标元素最近的、页面初始加载就存在的父容器上,减少事件冒泡的匹配开销。 - 不要混用两种绑定方式给同一个元素绑定同类型事件,避免出现重复触发、触发顺序不符合预期的问题。
内容的提问来源于stack exchange,提问作者rd1218
相关产品推荐
相关产品推荐

