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

Javascript 如何让jQuery触发本机自定义事件处理程序,javascript,jquery,Javascript,Jquery,有人知道让jQuery.trigger()触发由(而不是jQuery)本机JavaScript事件处理程序处理的自定义事件所需的魔力吗 test = document.querySelectorAll('.test')[0]; test.addEventListener('click', function() { console.log('click') }); test.addEventListener('custom', function(ev) { console.log(

有人知道让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?

编辑以添加:

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

在网页末尾,请参见:

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


我的想法是创建一个插件,作为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);
它由以下代码稍微修改:

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

test.addEventListener('test:custom', function(ev) {
  console.log('test:custom', ev.detail)
});
您可以通过以下方式发送:

$(test).trigger('test:custom', {  detail: '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在元素[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;
}
//在与事件同名的目标上调用本机DOM方法。
//无法在此处使用.isFunction()检查,因为IE6/7未通过该测试。
//不要在窗口上执行默认操作,这是全局变量的位置(#6170)

//没错,但这不是问题所在。我希望jQuery触发一个由本机(非jQuery)处理程序处理的自定义事件。很抱歉,我误解了这个问题。我喜欢你的想法,但遗憾的是,它并不真正适合我的用例。我将在问题描述中添加一个注释,并提供更多详细信息。不过,这是迄今为止对我最初问题的最好答案。
// 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;
}