如何让jQuery触发本机自定义事件处理程序

有没有人知道让jQuery .trigger()触发由( 不是jQuery )本机JavaScript事件处理程序处理的自定义事件所需的魔力?

 test = document.querySelectorAll('.test')[0]; test.addEventListener('click', function() { console.log('click') }); test.addEventListener('custom', function(ev) { console.log('custom', ev.detail) }); // Custom Native -> Native works as expected test.dispatchEvent(new CustomEvent('custom', {detail: 'detail'})); // -> "custom" "detail" // Standard jQuery -> Native works as expected $(test).trigger('click'); // -> "click" // Custom jQuery -> Native does not work $(test).trigger('custom'); // -> No log? $(test).trigger({type: 'custom'}); // -> No log? 

codepen.io实例

编辑添加:

关于我的用例的更多细节。 我正在开发一个依赖于自定义事件的库,但它本身并不使用jQuery。 但是,我想使这个库方便那些有jQuery的应用程序。

我的想法是创建一个插件,它将作为jquery中trigger函数的包装器:

 (function($) { $.fn.extend({ trigger: function(type, data) { return this.each(function() { if (typeof type == "string" && type.startsWith("test:")) { this.dispatchEvent(new window.CustomEvent(type, data)); }else{ jQuery.event.trigger(type, data, this) } }); } }); })(jQuery); 

它是稍微修改过的代码: https : //github.com/jquery/jquery/blob/master/src/event/trigger.js#L185

假设您按如下方式添加处理程序:

 test.addEventListener('test:custom', function(ev) { console.log('test:custom', ev.detail) }); 

您可以通过以下方式发送:

 $(test).trigger('test:custom', { detail: 'jquery'}); 

缺点是您需要使用某种命名空间为所有自定义事件添加前缀。

的jsfiddle

好吧,在调试器中单步执行jQuery源之后,看起来有一个解决方案。 不优雅,但可行。 诀窍是向元素添加onxxxx属性,其中xxxx是事件名称。 问题中代码的添加将是:

 test.oncustom = function(ev, data) { // ev is the jQuery Event object // data is data passed to jQuery `.trigger()` } 

请注意,jQuery不会将自定义数据添加到例如ev.detail ,就像标准事件的情况一样。 相反,它将自定义数据作为附加参数传递。

https://learn.jquery.com/events/introduction-to-custom-events/

在网页的最后看到:

以下是在两种情况下使用自定义数据的.on()和.trigger()的使用示例:

 $( document ).on( "myCustomEvent", { foo: "bar" }, function( event, arg1, arg2 ) { console.log( event.data.foo ); // "bar" console.log( arg1 ); // "bim" console.log( arg2 ); // "baz" }); $( document ).trigger( "myCustomEvent", [ "bim", "baz" ] ); 

这不是魔术。 这个问题位于jQuery在elem [type]上的解析过程中。 您的测试元素没有自定义处理程序,而是具有本机单击处理程序。

所以,你的脏修复可能看起来像:

 **test.custom = function () {console.log('custom fixed')};** 

请查看下面jquery-1.7.2.js的代码片段:

 // Call a native DOM method on the target with the same name name as the event. // Can't use an .isFunction() check here because IE6/7 fails that test. // Don't do default actions on window, that's where global variables be (#6170) // IE<9 dies on focus/blur to hidden element (#1486) if (ontype && elem[type] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow(elem)) { // Don't re-trigger an onFOO event when we call its FOO() method old = elem[ontype]; if (old) { elem[ontype] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; elem[type](); jQuery.event.triggered = undefined; if (old) { elem[ontype] = old; } 

}