有没有办法用jQuery手动触发委托的事件处理程序?
请参考以下示例代码:
<div class="container">
<input type="button" value="Hello">
<span class="output"></span>
</div>
<script>
$('.container')
.on('click', '[type=button]', function(e) {
$(e.delegateTarget).find('.output').text($(this).val());
})
.find('[type=button]').triggerHandler('click');
</script>
(在线:http://jsfiddle.net/TcHBE/)
我当时希望这会有效,并且文本“Hello”会出现在跨度中而不会实际点击按钮,但事实并非如此。
我在处理程序中使用e.delegateTarget
,因为.ouput
元素与按钮之间不存在已知关系,除了.container
内的某个位置。这就是我首先使用委托事件处理程序的原因。
更新
此外我正在使用triggerHandler
,因为事件在我不想触发的实际代码中有默认行为。 (在实际代码中,事件是Bootstrap Modal plugin的自定义事件hide
,但我实际上并不想在页面加载时触发事件处理程序时隐藏模态。
我可以将处理程序提取到一个命名函数中并直接调用它,但是由于使用了e.delegateTarget
,这会使构造更复杂。
答案 0 :(得分:49)
您可以手动创建一个Event对象,并相应地设置target
属性,以欺骗jQuery认为该事件冒出来了。
var c = $('#container');
c.on('click', '[type=button]', function(e) {
$(e.delegateTarget).find('span').text($(this).val());
});
var event = jQuery.Event('click');
event.target = c.find('[type=button]')[0];
c.trigger(event);
答案 1 :(得分:0)
.on()
方法中的选择器是可选的
当你写:
$('.container')
.on('click', '[type=button]', function(e) {
$(e.delegateTarget).find('.output').text($(this).val());
})
.find('[type=button]').triggerHandler('click');
您告诉事件处理程序只收听容器内的按钮单击
$(e.delegateTarget)
只是对外部容器的引用。
这是引用from the API:
提供选择器时,事件处理程序称为 授权。直接在事件发生时不会调用处理程序 绑定元素,但仅适用于后代(内部元素) 匹配选择器。 jQuery从事件目标起泡事件 到附加处理程序的元素(即最里面的) 最外面的元素)并为其中的任何元素运行处理程序 匹配选择器的路径。
答案 2 :(得分:0)
作为@Prinzhorn答案的补充,拥有以下JQuery函数可能会很有用:
(function( $ ){
$.fn.triggerParent = function (eventName, parent) {
this.each(function() {
var event = jQuery.Event(eventName);
event.target = this;
$(parent).trigger(event);
});
};
})( jQuery );
答案 3 :(得分:0)
我们可以将另外的event configuration
作为jQuery's $.Event()
传递给second argument
。更多信息here。
$('#click-me').on('click', function(evt){
$(document).trigger($.Event('custom-click', {target: evt.currentTarget}));
});
$(document).on('custom-click', '#click-me', function(evt){
alert(`${evt.type} was triggered on button with ${evt.target.id} id.`);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="click-me">Click Me</button>
祝你好运...
答案 4 :(得分:0)
我知道,这个问题很古老,但是当我在寻找另一个问题的答案时绊脚石时,我想我也可以在这里分享我稍微简单一点的方法。
想法是直接在所需的 target元素上直接创建事件:$(target_selector).trigger(event_type)
或-对于“ click”之类的标准事件甚至更短-执行$(target_selector).click()
,请参见我的小提琴在下面:
$(function(){
$('.container').on('click','button',function(){
console.log('delegated click on '+$(this).text());
return false;
});
$('#other').click(e=>$('.container button').trigger('click'));
$('#clickone').click(e=>$('.container .one').click());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="container">
<button type="submit" class="one">click 1</button> and another chance to click here on <button class="two">click 2</button>.
</form><br>
<div id="other">Trigger clicks on both buttons here!</div><br>
<div id="clickone">Trigger a click on button "one" only.</div>