5

I'm creating a custom event in plain Javascript and attaching it to a DOM element. The element has multiple event listeners for the same event. The code I've written is:

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

Now what I want is, get the data from last event handler like below:

var modifiedData = element.dispatchEvent(event);

Though I know the above line may not be correct, but I want something like that. If I use jQuery, there is pretty simple thing like $.triggerHandler I can use that iterates over all the listeners for a particular event and gives the return value of last handler if any.

But I want to do it in pure Javascript. Is there any solution for such kind of thing?

2 Answers 2

1

Just use the detail property and it should work just as you'd expect:

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>

Per comments, here's an idea how you could achieve what you're hoping to do:

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>

Sign up to request clarification or add additional context in comments.

3 Comments

So can't we get the retrun value?? I need only returned value. What if user returns completely a new object
@ManishJangir That's not how event handlers work in JS. To pass returned objects you're going to have to override addEventListener and wrap handlers into a handler of your own.
@ManishJangir I added an example how you could use return values.
0

The easiest way is to save all Event listener results to some object.
Like const eventObj = {};
So, after each event you can just Object.assign(eventObj, <yourDataFromEvent>
More about Object.assign() here

1 Comment

I'm developing a library and I don't expect users to use Object.assign. They can just return a value from the handler so that I can collect that value from the dispatcher.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.