【问题标题】:Chrome extension: detect when popup window closesChrome扩展:检测弹出窗口何时关闭
【发布时间】:2016-09-27 17:03:43
【问题描述】:

对于我的 chrome 扩展,我想在 browserAction 弹出窗口关闭时执行一个操作。我知道发生这种情况时不会触发任何内置事件。找到this suggestion与后台脚本打开一个连接,然后使用连接的port.onDisconnect事件检测弹窗正在关闭。

但是,当弹出窗口关闭时,我在后台脚本的开发者控制台中看到以下错误:

(BLESSED_EXTENSION context for glkehflnlfekdijfhacccflbffbjhgbd) extensions::messaging:102: Uncaught TypeError: Cannot read property 'destroy_' of undefined{TypeError: Cannot read property 'destroy_' of undefined
   at PortImpl.destroy_ (extensions::messaging:102:37)
   at dispatchOnDisconnect (extensions::messaging:322:29)}

我使用的脚本详述如下。

你能看出我哪里出错了吗?


manifest.json

{ "manifest_version": 2

, "name": "Detect when popup closes"
, "version": "0.1"

, "browser_action": {
    "default_icon": "popup.png"
  , "default_popup": "popup.html"
  }

, "background": {
    "scripts": [
      "background.js"
    ]
  }
}

popup.html

<!DOCTYPE html>
<body>
  <h1>Test</h1>

  <script src="popup.js"></script>  
</body>
</html>

popup.js

var port = chrome.runtime.connect()

background.js

chrome.runtime.onConnect.addListener(function (externalPort) {
  externalPort.onDisconnect = function () {
    try { 
      var ignoreError = chrome.runtime.lastError
    } catch (error) {
      console.log("onDisconnect")
    }
  }
)

【问题讨论】:

  • 建议是在后台脚本中检测事件。端口已断开因为弹出窗口已销毁,因此在端口断开时没有事件侦听器可调用。
  • @wOxxOm 正如您所建议的那样,我已经重写了我的基本扩展以在后台脚本中使用port.onDisconnect。但是,这只是将错误转移到弹出窗口关闭的那一刻。
  • 这种情况下的错误已记录在案,可以通过简单的赋值var ignoreError = chrome.runtime.lastError 忽略。重要的是断开连接侦听器实际上会触发。
  • @wOxxOm 我已经添加了你建议的任务,但我怀疑我是否把它放在了正确的位置。也许断开连接侦听器会触发,但该错误阻止我让它做任何有用的事情。
  • @JamesNewton 我回滚了您的“已解决”编辑;将来,请将您自己的解决方案(如果合适的话)作为单独的答案发布 - 自我回答绝对可以,但将答案混入问题中则不行。此外,无需在标题中将您的问题标记为已解决(有一个公认的答案就足够了)。

标签: google-chrome-extension popup


【解决方案1】:

作为参考,这里是 background.js 脚本的工作版本:

chrome.runtime.onConnect.addListener(function (externalPort) {
  externalPort.onDisconnect.addListener(function () {
    console.log("onDisconnect")
    // Do stuff that should happen when popup window closes here
  })

  console.log("onConnect")
})

【讨论】:

    【解决方案2】:

    onDisconnect 不是可分配的属性。
    它是一个提供addListener方法来注册回调的对象:

    externalPort.onDisconnect.addListener(function() {
        var ignoreError = chrome.runtime.lastError;
        console.log("onDisconnect");
    });
    

    【讨论】:

    • 我还建议将externalPort 保存到外部范围内的变量中;我认为否则它会冒垃圾收集的风险。
    • 是的,但只是为了稍后修改端口的行为。侦听器本身已在浏览器内部注册,因此它会保留下来。
    • 当弹出窗口关闭时如何让.onDisconnect 触发?每当我实现它时,它只会在实际的扩展程序被卸载时触发。
    • 应该在后台页面。
    • @wOxxOm 是否可以将 onDisconnect 侦听器放在内容脚本中而不是 background.js 中?我试过了,但无法让它工作。这将使我不必创建另一个注入脚本,因为我希望在关闭弹出窗口时运行的方法驻留在内容脚本中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多