Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dispatchEvent() with a function as param, executes the function instead of passing it

I'm trying to dispatch an event to window.top.document as

code in frame1:

function callingBell(){
    alert('ding dong');
}

 var event = window.top.document.createEvent("CustomEvent");
 event.initCustomEvent('READY', false, false, { 'bell': callingBell });
 window.top.document.dispatchEvent(event);

in frame2:

window.top.document.addEventListener('BOMREADY', function(e) {

    bell= e.detail.bell;

}, false);

More Details: I have a parent jsp. Within the parent jsp, I have 2 child jsps. The scenario works well the first time. When I refresh/reload the two child jsps while the parent frame is not refreshed- the above issue occurs. The number of times the alert "ding dong" is displayed is exactly the number of times I refresh the child frames. Meaning: on the 7th refresh, the alert appears 7 times. I suspect something in the window.top.document is currupted to execute the function before passing it to the listener.

On second refresh onwards, when execution reaches "window.top.document.dispatchEvent(event)", instead of getting into the target listener first, the callingBell function is called and the alert is displayed before the execution reaches the listener code.

Also, if callingBell is not a function, the listener is called once, as expected.

UPDATE: I can solve this problem by simply removing the event listener inside the addEventListener using:

  e.target.removeEventListener('READY', arguments.callee, false);

but, I can't do this as a final solution as I need the listener for a later event.

like image 597
stackMan10 Avatar asked Jul 19 '16 16:07

stackMan10


1 Answers

I suspect you get this issue because you do not remove the listener on your callback. This is why each time you actually refresh you stack your events and get multiples alerts.

This is how I would actually make this :

window.top.document.addEventListener('BOMREADY', _callback(e), false);

function _callback(e) {
  window.top.document.removeEventListener('BOMREADY', _callback(e), false);

  // Keep executing your function
  bell = e.detail.bell;
  bell();
}

Hope this helps !

like image 170
0x01 Avatar answered Oct 16 '22 16:10

0x01