我的.on()表现得像.bind(),而不是.live()

时间:2012-04-09 06:20:25

标签: jquery ruby-on-rails nested-forms

我有一个复杂的嵌套表单(Ryan Bates的版本),.live()附加了一些动态生成的元素,我现在正在转换到.on()以及从Jquery 1.4升级到1.7。

以下是~22个变化之一的样本:

# old version with .live()
$('.options .image').live('click', function(){
    console.log('clicked .options')
})

# new version with .on()
$('.options').on('click', '.image', function(){
    console.log('clicked .options')
})

这些更改对于已经存在的表单元素非常有效,但是对于之后动态创建的任何嵌套元素,它们都失败了。因此,它更像Jquery的bind而不是live。你知道这里会发生什么吗?

由于代码的复杂程度太高而且很多部分内容我现在都要离开(希望你有预感!)。感谢。

3 个答案:

答案 0 :(得分:3)

根据3nigma的评论,但使用原始选择器修改,这将起作用:

$(document).on('click', '.options .image', function() {
  console.log('clicked .options');
});

但是,我不认为将文档设置为监听器通常是要走的路。在包含.live()的原始版本中,您正在.image节点中选择.options个节点。

但问题并未说明哪些部分是动态加载的。我怀疑.options也是动态加载的内容的一部分。使用.on()委托侦听器时的第一个选择器必须是不被破坏的东西:

$('#someWrapper').on('click', '.options .image', function() {
  console.log('clicked .options');
});

#someWrapper不需要是一个新的包装元素,它可以是任何祖先(有些人称之为“父”......但这是用词不当,因为它可能是祖父母或曾祖父母或其他什么!)没有被破坏。越接近目标选择器(.options .image)越好。

答案 1 :(得分:3)

要使.on()代码生效,.options元素必须是静态的 - 不是动态创建的。 .on()的第一个选择器必须是静态父级。如果使用的话,它会像.live()一样工作:

$(document).on('click', '.options .image', fn);

但是,如果选择一个比document对象更接近对象的静态父级(未创建或销毁的父级),页面的性能会更好。由于您没有向我们展示您的HTML,我不推荐使用特定对象,但可能您可以选择正确的父对象。

答案 2 :(得分:0)

下面的

.on().live()

的正确语法
$(selector).live(events, data, handler);                // jQuery 1.3+
$(document).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(document).on(events, selector, data, handler);        // jQuery 1.7+

查看更多:

on v/s live
on and off