有没有办法通过自定义事件传递额外的数据?

Posted

技术标签:

【中文标题】有没有办法通过自定义事件传递额外的数据?【英文标题】:Is there any way of passing additional data via custom events? 【发布时间】:2012-03-14 02:22:05 【问题描述】:

我需要在两个自主用户脚本之间传递数据——最好不要接触unsafeWindow 对象——我认为使用自定义事件是可行的方法。我想到了这样的事情(为了示例的目的,让我们忽略 MSIE 模型):

addEventListener("customEvent", function(e) 
  alert(e.data);
);

var custom = document.createEvent("htmlEvents");
custom.initEvent("customEvent", true, true);
custom.data = "Some data...";
dispatchEvent(custom);

这在标准 javascript 环境和一个用户脚本中运行良好,但是当用户脚本触发事件并在其外部或另一个用户脚本内捕获时,data 属性在 Chromium 中为 undefined。我想我可以将传递的数据保存在sessionStorage 中,但这远非无缝。还有其他优雅的解决方案吗?完美需要和可以实现,我能感觉到。

【问题讨论】:

【参考方案1】:

是的,您可以使用MessageEventCustomEvent

示例用法:

//Listen for the event
window.addEventListener("MyEventType", function(evt) 
    alert(evt.detail);
, false);

//Dispatch an event
var evt = new CustomEvent("MyEventType", detail: "Any Object Here");
window.dispatchEvent(evt);

【讨论】:

要使用new CustomEvent('eventName') 构造函数来实现这一点,请将数据传递到CustomEventInit 哈希中,由'detail' 键入,如下所示:new CustomEvent('eventName', 'detail': data); 数据序列化了吗?我可以在其中添加对 HTML 元素的引用吗? +1 也用于使用CustomEvent。请注意,您应该使用detail 属性,只有在侦听器中的event.detail 下才可用。 这是一个非常令人困惑的答案。是新的 CustomEvent 还是 document.createEvent ? 对我来说detailevent.originalEvent【参考方案2】:

将具有更多详细信息的对象作为属性传递:

var event = new CustomEvent('build',  detail:  'detail1': "something", detail2: "something else" );

function eventHandler(e) 
  log('detail1: ' + e.detail.detail1);
  log('detail2: ' + e.detail.detail2);

https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

【讨论】:

这不是 JSON: foo: "bar" 这是一个 JavaScript 哈希。 JSON 有非常严格的规则(键必须用双引号括起来),即使相同的 JS 是有效的 JSON,在 JS 中使用它也只是 JS 而不是 JSON。在我看来,如果它是有效的 JSON 并且它存储为字符串,那么它只是 JSON。当它是 JS 代码时,它只是一个看起来像 JSON 的 JavaScript 数据结构。 哈希和 Json 对象之间的确切区别是什么?据我所知,我们可以像 var xyz=; xyz['index1']="myvalue1"; xyz['index2']="myvalue2"; @SujalMandal - 不同之处在于他根本没有正确使用 JSON 一词。那不是 JSON,那只是一个 javascript 对象文字。 JSON 是一种 string 格式,用于在程序/存储数据之间传输数据,其语法很大程度上基于 javascript 对象。 需要将'detail1': "something", detail2: "something else" 包装在一个名为detail 的属性中以使其工作:var event = new CustomEvent('build', detail: 'detail1': "something", detail2: "something else" );【参考方案3】:

new CustomEvent 在 IE 中不受支持 https://caniuse.com/#search=CustomEvent

这是一个同样适用于 IE9+ 的版本:

//Listen for the event
window.addEventListener("MyEventType", function(evt) 
     alert(evt.detail.test); //alerts "Any Object Here"
, false);

 //Dispatch an event
 var evt = document.createEvent('CustomEvent');
 evt.initCustomEvent('MyEventType', false, false,  test: "Any Object Here" );
 window.dispatchEvent(evt);

【讨论】:

此解决方案已被弃用。支持 IE9+ 的一种更面向未来的方法是使用 polyfill。另见developer.mozilla.org/en-US/docs/Web/API/CustomEvent/…

以上是关于有没有办法通过自定义事件传递额外的数据?的主要内容,如果未能解决你的问题,请参考以下文章

trigger 和 triggerHandler(),自定义事件

mui触发自定义事件(子页面返回传递给父级页面值)

通过父应用程序在模块之间传递自定义事件

Vue 组件之间传参!

vue组件-子组件向父组件传递数据-自定义事件

Vue-组件自定义事件