如果在文档加载后运行,事件侦听器会收到空详细信息

Posted

技术标签:

【中文标题】如果在文档加载后运行,事件侦听器会收到空详细信息【英文标题】:Event listener receives null detail if run after document loads 【发布时间】:2019-05-22 17:27:03 【问题描述】:

我一直在为 Chrome 开发一个扩展程序。

为了工作,它必须使用 CustomEvent 将网站设置的全局窗口变量传递给扩展程序的主脚本。 当页面加载到活动选项卡中时,这通常可以正常工作,但是当它作为非焦点选项卡加载时,或者当扩展脚本的执行被延迟时,侦听器接收到的事件对象具有 null 详细信息属性。

需要明确的是,事件的整个细节对象是null,而不仅仅是所需的变量。我已经通过将所需变量作为 JSON 字符串附加到文档来解决此问题,但我想了解该事件有什么问题。

相关部分代码如下。

manifest.json:

"content_scripts": [ 
          "js": [ "main.js", "jquery-3.3.1.js"],
          "matches": [ "*://*.site.com/*"],
          "run_at": "document_end"
        ],
"permissions": [ "declarativeContent", "activeTab", "storage", "*://*.site.com/*" ],
"web_accessible_resources": [ "injectedScript.js" ]

main.js:

$(function() 

        document.addEventListener('globalPasser', function(response) 
            if(response.detail)
                // store variables
            

        , true);

        var passGlobals = document.createElement('script');
        passGlobals.src = chrome.extension.getURL('injectedScript.js');
        (document.head||document.documentElement).appendChild(passGlobals);
        passGlobals.onload = function() 
            passGlobals.remove();
        ;
    

injectedScript.js:

var newEvent = new CustomEvent('globalPasser', detail:variable: neededGlobalVariable);
document.dispatchEvent(newEvent);

【问题讨论】:

感谢您的建议。有问题的扩展名是 chrome.google.com/webstore/detail/kinjamprove-continued/… 它在任何带有 cmets 部分的 Kinja 网站(如 avclub.com)上运行。 我至少可以从 Chrome 30 开始重现该错误。明天我会尝试找到第一个坏版本。同时您可以尝试 1) 通过 textContent 在 script 元素上注入代码; 2)通过window而不是document传递事件。 @wOxxOm 我得到了相同的结果,通过窗口传递事件并使用 textContent 注入代码。我也将内容脚本切换到了 document_start,但这似乎也没有什么不同。 crbug.com/917703 【参考方案1】:

解决方法/修复是通过 JSON 简单地“清理”数据:

document.dispatchEvent(
  new CustomEvent('globalPasser',
    JSON.parse(JSON.stringify(
      detail: 
        variable: neededGlobalVariable
      
    ))
  )
);

这种情况下的问题是由数据中存在的 JS 函数引起的 - 有时 - 可能是当站点仍在处理某些内容时。 DOM 节点也会导致同样的问题。

有意或无意,但 Chrome 会中止序列化整个 detail 对象并将其传输为 null,因为 https://crbug.com/85158 并且此行为与扩展消息传递奇怪地不同,后者跳过此类不可序列化的内容:foo: functionRef, bar: 123 已传输作为bar: 123

【讨论】:

以上是关于如果在文档加载后运行,事件侦听器会收到空详细信息的主要内容,如果未能解决你的问题,请参考以下文章

应用内购买获取空白 Sku 详​​细信息列表

负载侦听器上的 Discord.py Cog

将事件侦听器添加到我的页面会导致问题

1307文档的加载

带有谷歌日历的完整日历

为啥单击两次后我的事件侦听器与按钮解除绑定?