I had code like this:
我有这样的代码:
$('.remove-group').click(function () {
$(this).closest('tr').remove();
});
This worked fine until I needed to use delegated event handler to capture clicks for elements that will be added to the page in the future.
这工作正常,直到我需要使用委托事件处理程序来捕获将来将添加到页面的元素的点击。
$(document).on('click', '.remove-group', function () {
$(this).closest('tr').remove();
});
This no longer works because the this
keyword does not refer to the originating element.
这不再有效,因为this关键字不引用原始元素。
Any ideas?
Update
It would seem that in my efforts to simplify the code for my question I actually made it work. I was actually passing in a wrapped set that was assigned to a variable instead of the string selector.
似乎在我努力简化我的问题的代码时,我实际上使它工作。我实际上是在传递一个包装的集合,该集合被分配给变量而不是字符串选择器。
var $removeGroup = $('.remove-group');
$(document).on('click', $removeGroup, function () {
$(this).closest('tr').remove();
});
That doesn't seem to work when I do it that way.
当我这样做时,这似乎不起作用。
3 个解决方案
#1
22
Hope this helps someone:
希望这有助于某人:
$('#container').on('click', '.remove-group', function(event) {
$(this); // returns $('.remove-group') equivalent
$(event.target); // returns $('.remove-group') equivalent
$(event.delegateTarget); // returns $('#container') equivalent
});
Reference: http://api.jquery.com/event.delegateTarget/
Edit from question author:
I just want to clarify some of the mistakes I originally made.
我只想澄清一下我最初犯的一些错误。
It would seem the .on()
handler in jQuery has some specific usage that isn't clearly spelled out in the documentation.
看起来jQuery中的.on()处理程序有一些特定的用法,在文档中没有明确说明。
-
You can use
.on()
directly on the selector itself:您可以直接在选择器本身上使用.on():
$('button').on('click', function () { $(this).css('border', 'solid 1px red'); });
It will work, but it will NOT apply to any future elements dynamically added to the page with the same selector. This is different from the way
.live()
used to work. You must bind to the document object to catch future elements as well as current ones. This is because the selector is now the element you are listening on and it will catch all click events that bubble up to that element (document being one of the topmost elements to listen on). Then you pass the selector for the element you're interested in as a second argument after the event name.它可以工作,但它不适用于动态添加到具有相同选择器的页面的任何未来元素。这与.live()以前的工作方式不同。您必须绑定到文档对象以捕获将来的元素以及当前元素。这是因为选择器现在是您正在侦听的元素,它将捕获所有冒泡到该元素的单击事件(文档是要监听的最顶层元素之一)。然后,将您感兴趣的元素的选择器作为事件名称后面的第二个参数传递。
$(document).on('click', 'button', function () { $(this).css('border', 'solid 1px red'); });
Now the listener will filter out click events until it finds one that was originally fired on 'button' and bubbled up to document.
现在,侦听器将过滤掉单击事件,直到找到最初在“按钮”上触发并冒泡到文档的事件。
-
You must supply a string selector, not a wrapped set. This will not work:
您必须提供字符串选择器,而不是包装集。这不起作用:
var $buttons = $('button'); $(document).on('click', $button, function () { $(this).css('border', 'solid 1px red'); });
For examples, see this jsbin.
例如,请参阅此jsbin。
Basically you just have to listen on a higher scope than the dynamic element. This makes sense considering that the dynamic elements you want to listen for are, by definition, being added/removed after your code runs and registers your event listener.
基本上你只需要听一个比动态元素更高的范围。根据定义,在您的代码运行并注册事件监听器之后添加/删除您要监听的动态元素,这是有道理的。
#2
10
To get the "originating element for the event", you would use the target
property of the event object:
要获取“事件的原始元素”,您将使用事件对象的target属性:
$(document).on('click', '.remove-group', function (e) {
$(e.target).closest('tr').remove();
});
However, that approach probably isn't what you actually want, since the originating element might actually be a descendant of .remove-group
whose 'click' event simply bubbled up the targeted element - meaning you might remove the wrong row in the event of a nested table. In the context of the .on()
handler, this
does in fact refer to the element matched by .remove-group
. To bind to a delegated event on this element using .on()
, the syntax is as follows:
但是,这种方法可能不是你真正想要的,因为原始元素实际上可能是.remove-group的后代,其'click'事件只是冒出目标元素 - 意味着你可能会删除错误的行嵌套表。在.on()处理程序的上下文中,这实际上是指.remove-group匹配的元素。要使用.on()绑定到此元素上的委托事件,语法如下:
$(static-parent-element).on(event, selector-string, handler)
$(static-parent-element).on(event,selector-string,handler)
For example, this is the correct syntax:
例如,这是正确的语法:
$(document).on('click', '.remove-group', function () {
$(this).closest('tr').remove();
});
This will match current and future .remove-group
elements, and remove the nearest tr
ancestor. You can (and should) replace document
here with the closest parent element of .remove-group
which exists in the DOM at the time of binding, and will still exist whenever this event is expected to be triggered (i.e. is static). Doing this minimizes the distance which the event has to bubble up the DOM tree before the event is triggered.
这将匹配当前和将来的.remove-group元素,并删除最近的tr祖先。您可以(并且应该)使用绑定时存在于DOM中的.remove-group的最近父元素替换此文档,并且只要期望触发此事件(即静态),它仍然存在。这样做可以最小化事件在触发事件之前冒泡DOM树的距离。
#3
1
$(this)
should work fine but try event.target
in any case.
$(this)应该可以正常工作,但无论如何都要尝试event.target。
$(document).on('click', '.remove-group', function (event) {
$(event.target).closest('tr').remove();
});
#1
22
Hope this helps someone:
希望这有助于某人:
$('#container').on('click', '.remove-group', function(event) {
$(this); // returns $('.remove-group') equivalent
$(event.target); // returns $('.remove-group') equivalent
$(event.delegateTarget); // returns $('#container') equivalent
});
Reference: http://api.jquery.com/event.delegateTarget/
Edit from question author:
I just want to clarify some of the mistakes I originally made.
我只想澄清一下我最初犯的一些错误。
It would seem the .on()
handler in jQuery has some specific usage that isn't clearly spelled out in the documentation.
看起来jQuery中的.on()处理程序有一些特定的用法,在文档中没有明确说明。
-
You can use
.on()
directly on the selector itself:您可以直接在选择器本身上使用.on():
$('button').on('click', function () { $(this).css('border', 'solid 1px red'); });
It will work, but it will NOT apply to any future elements dynamically added to the page with the same selector. This is different from the way
.live()
used to work. You must bind to the document object to catch future elements as well as current ones. This is because the selector is now the element you are listening on and it will catch all click events that bubble up to that element (document being one of the topmost elements to listen on). Then you pass the selector for the element you're interested in as a second argument after the event name.它可以工作,但它不适用于动态添加到具有相同选择器的页面的任何未来元素。这与.live()以前的工作方式不同。您必须绑定到文档对象以捕获将来的元素以及当前元素。这是因为选择器现在是您正在侦听的元素,它将捕获所有冒泡到该元素的单击事件(文档是要监听的最顶层元素之一)。然后,将您感兴趣的元素的选择器作为事件名称后面的第二个参数传递。
$(document).on('click', 'button', function () { $(this).css('border', 'solid 1px red'); });
Now the listener will filter out click events until it finds one that was originally fired on 'button' and bubbled up to document.
现在,侦听器将过滤掉单击事件,直到找到最初在“按钮”上触发并冒泡到文档的事件。
-
You must supply a string selector, not a wrapped set. This will not work:
您必须提供字符串选择器,而不是包装集。这不起作用:
var $buttons = $('button'); $(document).on('click', $button, function () { $(this).css('border', 'solid 1px red'); });
For examples, see this jsbin.
例如,请参阅此jsbin。
Basically you just have to listen on a higher scope than the dynamic element. This makes sense considering that the dynamic elements you want to listen for are, by definition, being added/removed after your code runs and registers your event listener.
基本上你只需要听一个比动态元素更高的范围。根据定义,在您的代码运行并注册事件监听器之后添加/删除您要监听的动态元素,这是有道理的。
#2
10
To get the "originating element for the event", you would use the target
property of the event object:
要获取“事件的原始元素”,您将使用事件对象的target属性:
$(document).on('click', '.remove-group', function (e) {
$(e.target).closest('tr').remove();
});
However, that approach probably isn't what you actually want, since the originating element might actually be a descendant of .remove-group
whose 'click' event simply bubbled up the targeted element - meaning you might remove the wrong row in the event of a nested table. In the context of the .on()
handler, this
does in fact refer to the element matched by .remove-group
. To bind to a delegated event on this element using .on()
, the syntax is as follows:
但是,这种方法可能不是你真正想要的,因为原始元素实际上可能是.remove-group的后代,其'click'事件只是冒出目标元素 - 意味着你可能会删除错误的行嵌套表。在.on()处理程序的上下文中,这实际上是指.remove-group匹配的元素。要使用.on()绑定到此元素上的委托事件,语法如下:
$(static-parent-element).on(event, selector-string, handler)
$(static-parent-element).on(event,selector-string,handler)
For example, this is the correct syntax:
例如,这是正确的语法:
$(document).on('click', '.remove-group', function () {
$(this).closest('tr').remove();
});
This will match current and future .remove-group
elements, and remove the nearest tr
ancestor. You can (and should) replace document
here with the closest parent element of .remove-group
which exists in the DOM at the time of binding, and will still exist whenever this event is expected to be triggered (i.e. is static). Doing this minimizes the distance which the event has to bubble up the DOM tree before the event is triggered.
这将匹配当前和将来的.remove-group元素,并删除最近的tr祖先。您可以(并且应该)使用绑定时存在于DOM中的.remove-group的最近父元素替换此文档,并且只要期望触发此事件(即静态),它仍然存在。这样做可以最小化事件在触发事件之前冒泡DOM树的距离。
#3
1
$(this)
should work fine but try event.target
in any case.
$(this)应该可以正常工作,但无论如何都要尝试event.target。
$(document).on('click', '.remove-group', function (event) {
$(event.target).closest('tr').remove();
});