如何为jQuery动态生成的最后一个指定类元素绑定change事件
jQuery为动态生成的同类最后一个元素绑定事件的可行方案
事件委托的选择器参数不支持直接传入.class:last()这类动态集合筛选规则——这类筛选是执行代码瞬间对DOM集合做的静态截取,不会在事件触发冒泡阶段实时重新计算全量DOM匹配结果,直接写在委托选择器里无法达到预期效果。
针对你描述的「输入内容后追加新输入框、修改旧输入框不触发追加」的业务场景,最稳定的实现方式如下:
- 在事件委托的回调函数内,实时判断触发事件的元素是否为当前DOM树中该类的最后一个元素,匹配通过再执行业务逻辑
// 事件委托绑定到稳定存在的就近父元素即可,不一定要绑在body上,性能更好 $(".input-wrap").on("change", ".class", function(){ // 实时判断当前触发元素是不是当前最新的最后一个匹配元素 if ($(this).is($(".class").last())) { something(); // 这里放你的业务逻辑:生成新的同结构空输入框 } });
这个写法的优势:
- 只需要绑定一次,后续所有动态生成的元素都能响应事件,不需要重复绑定解绑
- 旧输入框触发change事件时,因为不是当前最后一个元素,判断逻辑直接拦截,不会重复生成新输入框
- 不受DOM结构变动影响,不管中间插入多少其他元素,只要判断逻辑执行时取全量同类元素的最后一个做对比,就不会出错
避坑说明
不要尝试直接在委托选择器里使用:last、:last-of-type这类选择器,比如下面的写法是无效的:
// 错误写法,无法达到预期效果 $("body").on("change", ".class:last", function(){ // 业务逻辑 })
原因是jQuery的事件委托是在事件冒泡到父元素时,检查触发事件的元素本身是否匹配传入的选择器,而:last是jQuery的集合筛选伪类,不是元素自身的固有属性,不会在每次事件触发时重新遍历全量DOM做集合计算。
另外一种每次生成新元素后解绑旧事件、给新元素重新绑定的写法也不推荐:
// 不推荐,维护成本高,容易出现漏绑、重复绑定问题 function bindChange() { $(".class").off("change").last().on("change", function(){ something(); bindChange(); }) } // 初始化执行 bindChange();
这种写法一旦有其他逻辑也会生成同类输入框,就容易出现事件绑定混乱的问题,稳定性远不如在回调内做实时判断的方案。
内容的提问来源于stack exchange,提问作者lk8a_2m
相关产品推荐
相关产品推荐

