【问题标题】:replacing jquery.live() with jquery.on() doesn't work用 jquery.on() 替换 jquery.live() 不起作用
【发布时间】:2011-12-30 23:50:32
【问题描述】:

我有几个在 ajax 调用后动态添加的文本框。这些框与当前工作正常的 .live() 事件处理程序相关联。我想用更新的 .on() 函数替换它。

这就是我所拥有的

$('.MyTextBox').live({
  mouseenter: function () { .... },
  mouseleave: function () { .... },
  blur: function () { ... }
});

当我用 .on() 替换 .live() 时,它不起作用;添加后,文本框不会显示其正常行为。

如果我写 $('#MainDiv .MyTextBox').live({... ,其中 MainDiv 是所有操作发生的顶部 DOM 元素,那么也不会发生任何事情。

我错过了什么?

谢谢

【问题讨论】:

  • 你怎么写.on()?因为它应该可以工作,但我真的很讨厌它的语法,很难判断它是否是委托。
  • @Matt: .live().delegate 做同样的基本事情(事件委托,通过在事件冒泡时测试事件目标)。不同之处在于.live() 在文档级别一直捕获事件,而.delegate() 将在您指定的任何位置捕获它们(即更近,更好)。所以,.on() 等价于 .live()$(document).on('event', '#selector .you > would've ~ used [with=live]', fn)。否则,.on() 的工作方式类似于 .bind().delegate(),具体取决于您是否提供选择器作为第二个参数。
  • @DaveWard .on() 与 .live() 完全不同,试试吧。据我所知,它只是在加载 DOM 时将事件处理程序附加到元素,因此与 .live() 不同,它不会在 DOM 已经加载后将处理程序附加到加载的节点。如果添加第二个选择器,它会将其视为 .delegate(),这与 live 完全不同。
  • @Matt:这里的误解可能是.live() 在将元素添加到 DOM 时不会附加新的处理程序。当您编写类似$('.targets').live('click', fn) 的内容时,实际发生的是jQuery 开始监视冒泡到文档对象的点击事件,检查它们的eventTarget 是否与.targets 匹配,如果匹配则执行您的函数。它使用与.delegate() 完全相同的方法,但在更接近它们发生的位置捕获冒泡事件的灵活性较低。使用 $(document).on('click', '.targets', fn) 做同样的事情。
  • @DaveWard 哦,好的,知道了。是的,这很有意义。

标签: jquery


【解决方案1】:

这是他们的例子,但有委托:

http://jsfiddle.net/HDtz3/

vs 非委托: http://jsfiddle.net/HDtz3/1/

这就是为什么我讨厌新的语法。

在你的简单做:

$('#MainDiv').on({
  mouseenter: function () { .... },
  mouseleave: function () { .... },
  blur: function () { ... }
}, '.MyTextBox');

它应该可以工作

【讨论】:

  • 好的,很酷;看起来一样,但显然它运行得更快。
  • @frenchie 是的,它看起来应该是一样的,它运行得更快的原因是因为它以一个元素为目标,而不是通过所有节点传播到那个元素。他们使用 .delegate() 进行了更改,基本上我认为他们所做的是将常规事件与委托结合起来,因此您可以使用 .on() 使它们“活”或不“活”
  • 我发现 #MainDiv 必须是非动态元素(不会通过 ajax 再次加载)。
  • 知道了。 $('可能发生事件的最近父级').on({...event actions...}, '发生变化的元素');
  • @Phelios 我添加了一个解释动态加载的答案。
【解决方案2】:

tl;dr:对于直接换入替换(考虑动态加载),请参阅下面的一般示例


正如其他海报所指出的,接受的答案有效,但 $(#MainDiv') 需要是 "non-dynamic element (not being loading again through ajax)"。这在性能方面是可取的,因为事件冒泡“距离”是有限的。在示例中,它只需要冒泡到要处理的父元素。

解决方案是绑定到不会重新加载的“最父”元素(通常通过 AJAX) - 在示例中,您需要绑定到 $('#MainDiv') 的父元素。

然而,

如果您确实想要直接替换live(),您只需绑定到document 元素即可。

通用示例

格式一:

//Replace:
$(selector).live(events, handler);           // Where `events` is a string

//With:
$(document)  .on(events, selector, handler); 

格式 2:

//Replace:
$(selector).live(events);                    // Where `events` is 
                                             //   an object of `handler`s
//With:                                      //   (as in OP's example)
$(document)  .on(events, selector);

请注意,on() 示例中,selector 的容器可以更改,绑定将自动应用;与live() 的功能相同。

OP的例子(格式2)

//Deprecated live() version:
$('.MyTextBox').live({
   mouseenter: function () { .... },
   mouseleave: function () { .... },
   blur: function () { ... }
});

//New on() version
$(document).on({
   mouseenter: function () { .... },
   mouseleave: function () { .... },
   blur: function () { ... }
},'.MyTextBox');

【讨论】:

  • 您的第二版OP's Example中的意思不是“.on”吗?
  • @Peter:感谢您的关注。我已经修好了。
【解决方案3】:

Aaron,Matt,我认为您的选择器顺序错误(用于live 转换),请查看on-http://api.jquery.com/on/#example-7 的 API 文档

$("body").on("click", "p", function(){
  //stuff
});

当我尝试您的方法时(我来这里寻找更新核心版本的解决方案),控制台错误弹出所有内容(1.8、1.9 和 2.0)。目标元素应该是第二个参数而不是最后一个。不知道为什么您的答案已被接受,因为它不起作用。希望这会有所帮助。

【讨论】:

  • 是一样的。见小提琴。
  • 有了所有 mambo jumbo,这是 .live() 最清晰的答案和最简单的替代品。我有点喜欢 .live(),可惜它被删除了。
  • Shadow Wizzrd,不一样,当我以目标元素作为最后一个参数的那种格式尝试时,它不起作用。
  • 我们的答案是正确的。请参阅我的 Format 1 示例,这是您在回答中引用的内容。 Matt 的回答和我的 Format 2 示例使用了 on 的不同“重载”,它接受一个对象作为第一个参数,选择器作为第二个参数,并且没有第三个参数。 为什么没有第三个 arg? 请注意,“格式 2”将事件和处理程序("click"function(){})组合到第一个 arg({click: function(){}})中,因此第三个 arg(处理程序)变为不必要的/多余的。
  • 无论哪种方式,目标元素始终是第二个参数(并且由于没有第三个参数的重载,也可能恰好是最后一个参数)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
  • 2018-04-27
  • 2018-03-15
相关资源
最近更新 更多