使用纯JavaScript从自定义事件处理程序中收集数据

5

我正在使用纯Javascript创建自定义事件,并将其附加到DOM元素上。该元素有多个相同的事件监听器。我编写的代码如下:

var element = document.getElementById('demo');

element.addEventListener("myCustomEvent", function(e) {
    console.log("myCustomEvent first handler triggered");
});
element.addEventListener("myCustomEvent", function(e) {
    console.log("myCustomEvent second handler triggered");
    e.data['otherKey'] = 'other value';
    return e.data;
});

// Trigger the event
var event = new CustomEvent("myCustomEvent", {
  data: {
    firstKey: 'first Value'
  }
});
element.dispatchEvent(event);

现在我想要的是,从上一个事件处理程序获取数据,就像下面这样:
var modifiedData = element.dispatchEvent(event);

我知道上面的代码可能不正确,但我需要类似的功能。如果我使用jQuery,有一个非常简单的方法$.triggerHandler可以用来迭代特定事件的所有监听器,并返回最后一个处理程序(如果有)的返回值。

但是我想在纯JavaScript中实现它。是否有此类问题的解决方案?

2个回答

1

只需使用 detail 属性,它应该按照您的期望工作:

var element = document.getElementById('demo');

element.addEventListener("myCustomEvent", function(e) {
    console.log("myCustomEvent first handler triggered");
    e.detail.otherKey = 'second value';
});
element.addEventListener("myCustomEvent", function(e) {
    console.log("myCustomEvent second handler triggered");
    console.log(e.detail);
});

// Trigger the event
var event = new CustomEvent("myCustomEvent", {
  detail: {
    firstKey: 'first Value'
  }
});
element.dispatchEvent(event);
<div id="demo"></div>

根据评论,以下是一个实现你所希望的功能的想法:

var element = document.getElementById('demo');

var originalFun = element.__proto__.addEventListener.bind(element);

var handlers = {};

var wrapperFun = function(e) {
  if (e.type in handlers) {
    var data = e.detail;
    handlers[e.type].forEach(function(fun){
      data = fun(data) || data;
    });
  }
};

element.__proto__.addEventListener = function(type, handler) {
  if (typeof handlers[type] === 'undefined') {
    handlers[type] = [];
    originalFun(type, wrapperFun);
  }
  handlers[type].push(handler);
};

element.addEventListener("myCustomEvent", function(e) {
    console.log("myCustomEvent first handler triggered");
    e.otherKey = 'second value';
    return e;
});
element.addEventListener("myCustomEvent", function(e) {
    console.log("myCustomEvent second handler triggered");
    console.log(e);
});

// Trigger the event
var event = new CustomEvent("myCustomEvent", {
  detail: {
    firstKey: 'first Value'
  }
});
element.dispatchEvent(event);
<div id="demo"></div>


那我们不能得到返回值吗?我只需要返回的值。如果用户完全返回一个新对象怎么办? - Manish Jangir
@ManishJangir 这不是JS中事件处理程序的工作方式。要传递返回的对象,您需要覆盖addEventListener并将处理程序包装到自己的处理程序中。 - Schlaus
@ManishJangir 我添加了一个示例,展示如何使用返回值。 - Schlaus

0
最简单的方法是将所有事件监听器结果保存到某个对象中。
例如:const eventObj = {};
因此,在每个事件之后,您只需Object.assign(eventObj, <yourDataFromEvent>
更多关于Object.assign() 在这里

我正在开发一个库,不希望用户使用 Object.assign。他们可以从处理程序中返回一个值,以便我可以从调度程序中收集该值。 - Manish Jangir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接