在jQuery中,您可以执行以下操作:
$('#j_unoffered').on('click', '.icon_del', function () {...
如果点击任何具有类j_unoffered
的后代元素,则会在元素icon_del
上放置一个处理程序。此外,它适用于任何后续创建的icon_del
元素。
我可以在Closure中正常工作,点击在元素本身上。
goog.events.listen(
goog.dom.getElement('j_unoffered'),
goog.events.EventType.CLICK,
function(e) {...
如何以与jQuery示例相同的方式在Closure中指定适用于其子/后代的父事件目标?
我假设我需要以某种方式使用setParentEventTarget
,但我不确定如何为DOM事件实现它。我发现的大多数文档都与自定义调度事件有关。
- 更新 -
我想知道这个相当简单的解决方案是否有任何问题:
goog.events.listen(
goog.dom.getElement('j_unoffered'),
goog.events.EventType.CLICK,
function(e) {
if (e.target.className.indexOf('icon_del') !== -1) {...
它仍将this
绑定到父级,但e.target
允许解决方法。 listen
(opt_handler)中的第五个参数允许您将this
绑定到其他内容,所以我猜这也是一个途径。
答案 0 :(得分:5)
我也不知道这种可能性,所以我建议其他代码:
var addHandler = function(containerSelector, eventType, nestSelector, handler) {
var parent = goog.isString(containerSelector) ?
document.querySelector(containerSelector) :
containerSelector;
return goog.events.listen(
parent,
eventType,
function(e) {
var children = parent.querySelectorAll(nestSelector);
var needChild = goog.array.find(children, function(child) {
return goog.dom.contains(child, e.target);
});
if (needChild)
handler.call(needChild, e);
});
});
用法:
addHandler('#elem', goog.events.EventType.CLICK, '.sub-class', function(e) {
console.log(e.target);
});
<强>更新强>:
如果您将使用此e.target.className.indexOf('icon_del')
,则可能会错过正确的事件。考虑一个id = container
的容器div,它有几个带有类innerContainer
的div,每个div包含几个class = finalDiv
的div。并且考虑您将使用上面的代码添加事件处理程序,这将检查innerContainer
类的e.target。问题是,当用户点击finalDiv
时,您的处理程序将被调用,但事件目标将是finalDiv
,不是innerContainer
,而是由它包含。你的代码会错过它,但不应该。我的代码检查e.target是否有嵌套类或包含它,所以你不会错过这样的事件。
opt_handler
也不能真正帮助你,因为你可能会有许多嵌套元素(你会把它们传递到这里?可能全部,但没有那么有用,你可以在事件中得到它们)处理程序,你可以随后动态添加,所以当你添加处理程序时,你无法了解它们。
总之,我认为在事件处理程序中完成这样的工作是合理且最有效的。
答案 1 :(得分:3)
您所指的是event delegation
seems使用Google Closure库这是不可能的(开箱即用);所以我的建议是使用jQuery或其他提供此功能的类似事件处理库。如果这是不可能的,或者你想亲手做到这里是一种可能的方法(注意:这不是生产用途)
var delegateClick = function(containerId, childrenClass, handler){
goog.events.listen(goog.dom.getElement(containerId), goog.events.EventType.CLICK, function(event){
var target = event.target;
//console.log(event);
while(target){
if ( target.className && target.className.split(" ").indexOf(childrenClass)!== -1) {
break;
}
target = target.parentNode;
}
if(target){
//handle event if still have target
handler.call(target, event);
}
});
}
//then use it, try this here: http://closure-library.googlecode.com/git/closure/goog/demos/index.html
//..select the nav context
delegateClick( 'demo-list' ,'goog-tree-icon', function(event){console.log(event);})
以下是对event delegation
的更深入分析