我有一个div MyClass类,我想连接两个处理程序。这个类是动态生成的,这就是我正在做的事情:
$('#MainDiv').on({
click: function () { Handler1($(this)); }
}, '.MyClass');
$('#SpecialChildDiv').on({
click: function () { Handler2($(this)); }
}, '.MyClass');
如何控制首先调用哪个处理程序? Handler2会做一些额外的工作但是并没有在每个MyClass上调用它,因为它不在SpecialChildDiv中。我希望Handler 2被称为AFTER Handler1。
感谢。
答案 0 :(得分:1)
因为SpecialChildDiv
可能是MainDiv
的后代,所以它将首先被调用。这是因为事件从目标中冒出来,并按顺序调用沿途向上发现的处理程序。
一种可能性是使用Handler2
在SpecialChildDiv
处理程序异步中调用setTimeout
。
$('#MainDiv').on({
click: function () {
Handler1($(this));
}
}, '.MyClass');
$('#SpecialChildDiv').on({
click: function () {
setTimeout($.proxy(function() {
Handler2($(this));
}, this), 0);
}
}, '.MyClass');
因此,处理程序本身将立即被调用,但是Handler2
函数将在Handler1
被调用之后才会运行。
我还使用$.proxy
在传递给this
的函数中保留了正确的setTimeout
值。
有点偏离主题,但如果您更改Handler1
和Handler2
以便this
是对元素的引用,而不是将其作为参数传递,则可以使代码更清晰...
$('#MainDiv').on({
click: Handler1
}, '.MyClass');
$('#SpecialChildDiv').on({
click: function () {
setTimeout($.proxy(Handler2, this), 0);
}
}, '.MyClass');
您只需在函数内部执行$(this)
即可将元素包装在jQuery对象中。虽然如果有其他参数可以通过,这可能没有用。
根据您在下面的评论,似乎需要将此技术应用于各种后代元素。
要干掉代码,您可以为点击处理程序创建一个工厂......
function async_handler_factory(the_handler) {
return function() {
setTimeout($.proxy(function() {
the_handler($(this));
}, this), 0);
};
}
...然后像这样使用它......
$('#MainDiv').on({
click: Handler1
}, '.MyClass');
$('#SpecialChildDiv').on({
click: async_handler_factory(Handler2)
}, '.MyClass');
$('#AnotherChildDiv').on({
click: async_handler_factory(Handler3)
}, '.MyClass');
所以这是相同的原则。只需将HandlerN
函数传递给async_handler_factory
,它就会创建并返回click
处理函数,它通过调用HandlerN
来执行与原始代码相同的操作。 setTimeout
。
为了避免混淆$.proxy
,这里有一个消除它的更新版本。
function async_handler_factory(the_handler) {
return function() {
var self = this;
setTimeout(function() {
the_handler($(self));
}, 0);
};
}
这表明实际上是setTimeout
使您的解决方案有效。
编辑:在不同的地方为async_handler_factory
提供了不同的名称。固定的。
答案 1 :(得分:0)
所以不要在点击时调用第二个 - 在第一个处理程序完成后调用它:
$('#MainDiv').on({
click: function (e) {
Handler1($(this));
if ($(e.target).attr('id')==="SpecialChildDiv") {
specialChildClick();
}
}
}, '.MyClass');
specialChildClick = function () {
Handler2($('#SpecialChildDiv'));
}