【问题标题】:Emit message to add-on from content script onbeforeunload?从内容脚本 onbeforeunload 向插件发送消息?
【发布时间】:2012-08-23 13:41:43
【问题描述】:

我有一个内容脚本,它计算用户浏览页面的时间。为此,我将一个内容脚本注入每个页面,启动一个计时器,然后在触发 onbeforeunload 事件时向插件发送一条消息。

但是,消息似乎永远不会传递给后台脚本。

鉴于我的main.js 看起来像这样:

var pageMod = require('page-mod'),
    self = require("self");

pageMod.PageMod({
  include: "http://*",
  contentScriptFile: [self.data.url('jquery.min.js'),
                      self.data.url('content.js')],
  onAttach: function(worker) {
    worker.port.on('pageView', function(request) {
      console.log("Request received");
    });
  }
});

我可以使用以下代码向main.js发送消息没有问题。

self.port.emit('pageView', { visitTime: time });

但是,当我尝试在用户离开页面时执行此操作时遇到了问题。当我这样做时,永远不会收到消息:

$(window).bind('onbeforeunload', function(e) {
  self.port.emit('pageView', { visitTime: time });
  // This should prevent the user from seeing a dialog.
  return undefined;
});

我也尝试过收听beforeunload,但这也不起作用。可能是什么问题?

【问题讨论】:

  • 文件准备好后,您是否绑定onbeforeunload?其次,您是否尝试直接附加事件? window.onbeforeunload = function(e) { self.port.emit('pageView', { visitTime: time }); // This should prevent the user from seeing a dialog. return undefined; }; 在 jsfiddle 中将 onbeforeunload 与 jQuery 绑定不起作用,直接方法起作用
  • 我很确定我确实尝试了直接方式(几天前提出了这个问题),但我会再试一次并回复你。绑定是在 jQuery 准备好之后发生的,所以应该没问题。
  • try this fiddle 并以不同的顺序放置 jquery 和 javascript。如果我在 jquery 中放置 onbeforeunload,我会看到 100% 由 javascript 处理,而没有由 jQuery 处理。如果在 jQuery 中使用 beforeunload,我会看到间歇性行为。因此我认为 javascript 是最稳定的。您可能会遇到的另一件事是:并非所有代码似乎都已执行。尝试在代码中添加alert("something");,您将看不到它正在执行。如果你用字符串替换return undefined,至少你应该看到一个对话框来确认离开页面
  • 好吧,多玩一点。我可以复制您在小提琴中提到的所有行为,但它似乎在 FF 附加组件中不起作用。据我所知,self.port.emit 函数没有在 unload 函数体中执行,就像对 alert() 的调用没有执行一样。
  • 确实,在事件处理程序中执行内容可能会出现问题。作为最后的努力,您可以尝试将您的代码放入超时 setTimeout(function() { <your code> },0); 使用 0 或 1 作为时间。

标签: javascript firefox firefox-addon firefox-addon-sdk dom-events


【解决方案1】:

内容脚本在 Firefox 浏览器插件中访问的 window 对象是一个代理对象,可能有点喜怒无常。使用window.addEventListener 会起作用。

window.addEventListener('beforeunload', function(e) {
  # Do stuff then return undefined so no dialog pops up.
  return undefined
});

【讨论】:

    【解决方案2】:

    onbeforeUnload 事件不是synchronous,所以浏览器垃圾在页面完成之前收集。使用synchronous AJAX request:

    function Data() 
     {
     var client = new XMLHttpRequest();
     client.open("GET", "/request", false); // third paramater indicates sync xhr
     client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
     client.send({ visitTime: time });
     client.onreadystatechange = emitter;
     }
    
    function emitter()
     {
     self.port.emit('pageView', { visitTime: time });
     }
    

    return a string 作为替代。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-12
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 2014-07-03
      • 2014-02-04
      • 1970-01-01
      相关资源
      最近更新 更多