为什么我的参数没有传递到分派事件?

20

我已经设置了一个像这样的事件监听器...

window.addEventListener('message', parseMessage, false);

var parseMessage = function(rawMessage) {
    console.log(rawMessage.cmd);
};

然后我会像这样触发事件:

var event = new Event('message', {'cmd':"blerg!"});

window.dispatchEvent(event);

问题在于parse message中的console.log记录下了undefined,而我期望它记录下"blerg!"。在这里我做错了什么?如何将'cmd'消息传递到事件中?


2个回答

49
  1. 使用CustomEvent代替Event来创建自定义事件。

  2. 将你的数据放到一个“details”对象中(见代码)。

  3. 我更改了事件名称,因为message也用于postMessage API。在Chrome中运行时这并不会引起问题,但我不建议这样使用。

var parseMessage = function(rawMessage) {
  console.log(rawMessage);
  console.log(rawMessage.detail.cmd);
};

// changed event name
window.addEventListener('myMessage', parseMessage, false);

// data should be in a 'details' object
var evt = new CustomEvent('myMessage', {
    detail: {
      'cmd' : "blerg!"
    }
});

window.dispatchEvent(evt);

这里是针对 IE >= 9 兼容性的一项调整(使用 document.createEvent()CustomEvent::initCustomEvent()):

var evt = document.createEvent("CustomEvent");
evt.initCustomEvent('myMessage', false, false, {
    'cmd': "blerg!"
});

太棒了,谢谢。我只是想知道,它必须在名为“detail”的JSON内部吗?还是这是你添加的内容? - CafeHey
1
@Smickie,您的自定义数据必须存储在“detail”键中。否则它将无法工作。(顺便说一下,“json”不是正确的术语。“detail”被称为“键”)。 - ComFreek
不错的回答。顺便说一下,Object Literal 是你要找的术语 typeof ({detail:{cmd:'blerg!'}}).detail ;-) - LessQuesar
值得一提的是,您可以使用Modernizr来检测是否支持CustomEvent,然后选择使用哪种方法来创建事件。 - Stephen Garside
1
请参考@olefrank的答案中的MDN Polyfill。 - Ilker Cat

27

如果要为IE9/10提供polyfill,您可以使用Mozilla提供的以下代码:
https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent

(function () {
  if (
      typeof window.CustomEvent === "function" ||
      // In Safari, typeof CustomEvent == 'object' but it otherwise works fine
      this.CustomEvent.toString().indexOf('CustomEventConstructor')>-1
  ) { return; }

  function CustomEvent ( event, params ) {
    params = params || { bubbles: false, cancelable: false, detail: undefined };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
   }

  CustomEvent.prototype = window.Event.prototype;

  window.CustomEvent = CustomEvent;
})();

这里也有描述,但链接错误: https://dev59.com/wmYq5IYBdhLWcg3wmRoD#22946340


1
这也修复了在IE11中的问题。 - Benjamin Intal
1
不仅需要修复IE9/10,还需要修复IE11 ;) - Ilker Cat
感谢您的修复。 - anlijudavid
我还不得不添加这行代码 window.Event = CustomEvent; 来支持 IE11,以便支持类似 new Event("myEvent") 的代码。 - Jay

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