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

How to get jQuery to trigger a native custom event handler

本文关键字:本机 自定义 程序 事件处理 jQuery 何获取 获取      更新时间:2023-09-26

有谁知道让 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源代码后,看起来有一个解决方案。不优雅,但可行。诀窍是向元素添加一个 onxxxx 属性,其中 xxxx 是事件名称。问题中对代码的添加将是:

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

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

我的想法是创建一个插件,它将作为 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

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;
}

}