jQuery-在单个事件处理程序中组合选择器的问题 [英] jQuery - Issues with combining selectors in a single event handler

查看:72
本文介绍了jQuery-在单个事件处理程序中组合选择器的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是关于Patrick DW对我对这个问题的回答的评论.

This is regarding Patrick DW's comment on my answer to this question.

多个选择器:确定触发者吗?

我的答案:

使用$(this)将为​​您提供被点击的元素.并使用 is()可以帮助您确定点击的内容.

Using $(this) will get you the element that was clicked.. and using is() can help you determine what was clicked.

$('a.button, span.xyz, a.another').click(function(e) {
   if ($(this).is("a.button")) {
     alert("a.button was clicked");
   } else if ($(this).is("span.xyz")) {
     alert("span.xyz was clicked");
   } else if($(this).is("a.another")) {
     alert("a.another was clicked);
   }
});

帕特里克的评论

这样做的麻烦之处在于,它有效地结合了.delegate()的低效率(针对选择器进行测试)与分配多个冗余处理程序的低效率.因此,您会遇到两全其美的情况.

Trouble with this is that it is effectively combining the inefficiency that .delegate() suffers (testing against a selector) with the inefficiency of assigning multiple redundant handlers. So you get the worst of both worlds.

@John-是的,将它们分成单独的处理程序,并将它们共享的所有常用功能放入可以从处理程序中调用的命名函数中,将更有意义.这消除了在每次事件发生时都运行.is()测试的需要,因为这可能会造成很大的代价.有时测试单击的元素可能会很有用.这就是.delegate()所做的.您要承担测试的费用,但要从减少分配的处理程序数量中获益

@John - Yes, it would make more sense to break them up into separate handlers, and place any common functionality they share into a named function that can be called from within the handlers. This eliminates the need to run the .is() tests at every event occurrence, which can be costly. It can sometimes be beneficial to test for the element that was clicked. This is what .delegate() does. You suffer the expense of the test, but gain from the reduced number of handlers being assigned

有人可以详细解释帕特里克(Patrick)所说的效率低下吗?为什么在这种情况下.is()昂贵?您还可以使用.delegate()

Could someone explain (in detail) the inefficiencies that Patrick is talking about? Why is .is() costly in this scenario? Can you give an example as well using .delegate()

推荐答案

使用jQuery的.delegate()方法会降低性能,因为每次事件在具有委托处理程序的元素内发生时,都需要进行类似的测试来确定哪个元素收到了事件.

Using jQuery's .delegate() method suffers a performance hit because every time the event occurs inside the element with the delegate handler, a similar test needs to take place to determine which element received the event.

这通常是值得的,因为通过使用.delegate(),您(大概)避免了为每个元素分配单独的处理程序的需求.

This is often worthwhile because by using .delegate() you are (presumably) avoiding the need to assign individual handlers to every element.

使用上面的代码,您需要分配多个处理程序的开销,并且您仍在运行需要测试以查看哪个事件接收到的代码.

With the code above, you have the overhead of assigning multiple handlers, and you are still running the code that needs to test to see which received the event.

很难说,如果是你提到的问题,适当的选择,但它会更好分配单独的处理程序,并避免测试.

Hard to say if .delegate() is the appropriate choice for the question you referenced, but it would be much better to assign individual handlers, and avoid the if( $(this).is('something') ) tests.

如果原始OP代码的目的是为每种元素类型都具有单独的功能,但仍然让它们共享一些通用功能的子集,则最好将该通用功能放入其自己的命名函数中并对其进行调用.这是一种更有效的方法.

If the purpose of the original OP's code was to have individual functionality for each element type, but still have them share some subset of common functionality, it would be better to roll that common functionality into its own named function and call it. This is a much more efficient approach.

以这个例子为例.假设span.targetp.anothertaget元素用于获取处理程序.如您所见,容器中有许多元素.

Take this example. Let's say the span.target and p.anothertaget elements are to get handlers. As you can see, there are a number of elements in the container.

使用选择器分配.click(),您最终得到几个单独的事件处理程序.

Using selectors to assign a .click(), you end up with several separate event handlers.

$('span.target').click(function() { /* do something with span */ });
$('p.anothertarget').click(function() { /* do something with p */ });

html

<div id='container'>
    <span class='target'>click me</span>             <!-- i get a handler -->
    <div>i don't do anything</div>
    <p class='anothertarget'>i get a click too</p>   <!-- i get a handler -->
    <span class='target'>click me</span>             <!-- i get a handler -->
    <div>i don't do anything</div>
    <p class='anothertarget'>i get a click too</p>   <!-- i get a handler -->
    <span class='target'>click me</span>             <!-- i get a handler -->
    <div>i don't do anything</div>
    <p class='anothertarget'>i get a click too</p>   <!-- i get a handler -->
    <span class='target'>click me</span>             <!-- i get a handler -->
</div>

这意味着jQuery需要为所有这些元素管理单独的处理程序.这是不利的一面.好处是您无需运行选择器即可查看收到该事件的内容.它总是用this表示(假设您为pspan使用了单独的功能.

This means that jQuery needs to manage individual handers for all of these elements. This is the downside. The upside is that you don't need to run a selector to see what received the event. It will always be represented by this (assuming you used separate functions for the p and the span.

使用.delegate(),仅将处理程序分配给容器.对于应触发事件的每种类型的元素,都会完成此操作.

Using .delegate(), you assign a handler only to the container. This is done for each type of element that should trigger an event.

如您所见,仅分配了两个处理程序.一个用于<p>元素,另一个用于<span>.这显然减少了所需处理程序的数量.但是代价是jQuery需要针对在container内部发生的每个事件运行传递给.delegate()的选择器,以查看哪种类型的元素实际接收了该事件.

As you can see, there are only two handlers assigned. One for the <p> element, and the other for the <span>. This obviously reduces the quantity of handlers needed. But the expense is that jQuery needs to run the selectors that you passed to .delegate() for each event that occurs inside container to see which type of element actually received the event.

所以有一些让步.

$('#container').delegate('span.target','click',function() { /* do something with span */ });
               .delegate('p.anothertarget','click',function() { /* do something with p */ });

html

<div id='container'>   <!-- i get a handler for the span.target -->
                       <!--             and for p.anothertarget -->
    <span class='target'>click me</span>             
    <div>i don't do anything</div>
    <p class='anothertarget'>i get a click too</p> 
    <span class='target'>click me</span>   
    <div>i don't do anything</div>
    <p class='anothertarget'>i get a click too</p> 
    <span class='target'>click me</span> 
    <div>i don't do anything</div>
    <p class='anothertarget'>i get a click too</p> 
    <span class='target'>click me</span>
</div>

上一个答案中的代码的麻烦在于,它有效地结合了第一个示例的效率低下(分配了许多处理程序)和第二个示例的效率低下(运行选择器).这就是我所说的两全其美.

The trouble with the code in your previous answer was that it was effectively combining the inefficiency of the first example (many handlers being assigned) with the inefficiency of the second example (running a selector). That's what I meant by the worst of both worlds.

这篇关于jQuery-在单个事件处理程序中组合选择器的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆