我想知道为什么在jQuery addEventListener("click", function(){})
触发时没有调用.trigger("click")
,但是在dispatchEvent(new Event("click"))
触发时调用它。
var el = document.getElementById("foo");
$(el).click(function() { console.log("jquery click"); });
el.onclick = function() { console.log("onclick"); };
el.addEventListener("click", function() { console.log("addEventlistener click"); });
$(el).trigger("click");
console.log("--------");
el.dispatchEvent(new Event("click"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#foo" id="foo">foo</a>
这会产生以下控制台输出
(index):54 jquery click
(index):55 onclick
(index):59 --------
(index):54 jquery click
(index):55 onclick
(index):56 addEventlistener click
我错过了什么吗? jQuery是否通过直接调用它的事件监听器来“伪造”一次点击?
答案 0 :(得分:5)
jQuery的trigger
触发jQuery处理程序并调用元素上的.event()
函数* - 除非它是click
元素上的a
,在这种情况下,它不会做第二部分。 (它还特别对待复选框。)例如,如果我们在您的示例中使用div
,我们会看到它:
var el = document.getElementById("foo");
$(el).click(function() { console.log("jquery click"); });
el.onclick = function() { console.log("onclick"); };
el.addEventListener("click", function() { console.log("addEventlistener click"); });
$(el).trigger("click");
console.log("--------");
el.dispatchEvent(new Event("click"));
<div id="foo"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
...但不在a
上:
var el = document.getElementById("foo");
$(el).click(function() { console.log("jquery click"); });
el.onclick = function() { console.log("onclick"); };
el.addEventListener("click", function() { console.log("addEventlistener click"); });
$(el).trigger("click");
console.log("--------");
el.dispatchEvent(new Event("click"));
<a href="#foo" id="foo">foo</a>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
为什么不呢?对于“跨浏览器一致性”,消息来源说:请参阅https://github.com/jquery/jquery/blob/master/src/event.js#L476(该链接是一个行号,因此可能会腐烂):
click: {
// For checkbox, fire native event so checked state will be right
trigger: function() {
if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
this.click();
return false;
}
},
// For cross-browser consistency, don't fire native .click() on links
_default: function( event ) {
return nodeName( event.target, "a" );
}
},
注意最后一点。
*找到这个有点棘手。 trigger
says:
当相应的事件发生时,会触发任何事件处理程序附加
.on()
或其中一种快捷方法。但是,可以使用.trigger()
方法手动触发它们。
...但是triggerHandler
says:
此方法的行为类似于
.trigger()
,但以下情况除外:
.triggerHandler( "event" )
方法不会在触发的元素上调用.event()
。这意味着表单上的.triggerHandler( "submit" )
不会在表单上调用.submit()
。.trigger()
将对jQuery对象匹配的所有元素进行操作,但.triggerHandler()
仅影响第一个匹配的元素。.triggerHandler()
触发的事件不会冒出DOM层次结构;如果他们没有被目标元素直接处理,他们什么都不做。.triggerHandler()
不返回jQuery对象(允许链接),而是返回它导致执行的最后一个处理程序返回的任何值。如果没有触发处理程序,则返回undefined 在这一点上肯定会更清楚。
答案 1 :(得分:0)
trigger()一直是我的问题。
API说:
执行所有处理程序以及附加到匹配元素的行为 对于给定的事件类型。
http://api.jquery.com/trigger/
addEventListener的行为与内联点击事件不同,浏览器会以不同的方式解释泡泡: https://www.w3.org/TR/DOM-Level-3-Events/#event-flow
当您发送时,您正在创建一个绕过这些限制的自定义事件: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
因此,dispatch可以解决这些限制,而trigger()会尝试为您完成这项工作。