【问题标题】:Firefox onLocationChange not always calledFirefox onLocationChange 并不总是被调用
【发布时间】:2013-11-20 21:37:10
【问题描述】:

我正在构建一个创建多个隐藏浏览器元素的 Firefox 扩展。

我想addProgressListener() 为我加载的页面处理 onLocationChange。但是,我的处理程序并不总是被调用。

更具体地说,这就是我正在做的事情:

  1. 创建浏览器元素,但不设置其src 属性
  2. 将其附加到另一个元素
  3. 将监听onLocationChange 的进度监听器添加到浏览器元素
  4. 使用所需网址致电loadURIWithFlags() 并发布数据

我希望处理程序在 4 之后每次都被调用,但有时它不会(但它似乎卡在相同的页面上)。

有趣的是,如果我将 3 和 4 包装在 setTimeout(..., 5000); 中,它每次都有效。

我也尝试过改组一些步骤,但没有任何效果。

更大的图景:当浏览器的contentDocument 是新加载页面的contentDocument 时(重定向后),我希望得到可靠的通知。有没有更好的方法来做到这一点?

更新:我已经在 mozilla 的错误跟踪器上打开了一个错误,其中包含显示此行为的最小 xulrunner 应用程序,以防有人想仔细查看:https://bugzilla.mozilla.org/show_bug.cgi?id=941414

【问题讨论】:

  • 我们能得到一些代码/小提琴吗?你如何设置你的听众?
  • @Cracker0dks 有一个最小的 xulrunner 应用程序附加到该错误:bugzilla.mozilla.org/show_bug.cgi?id=941414
  • 我意识到这是一个简化的测试用例,但你想完成什么?为什么使用 onLocationChange 而不是简单的负载监听器?为什么使用 而不是
  • 我实际上这样做是为了可以收听load事件。当第一次创建浏览器元素时,它的contentDocument 没有指向正确的页面(它指向about:blank)。只有在onLocationChange 被触发后,contentDocument 才会更新为指向新页面(或者至少这是我能找到的最早的页面)。
  • 抱歉,忘记回复您声明的第二部分。我需要它是一个浏览器元素,因为我需要它的行为就像用户正在访问该站点一样,包括执行 javascript。一些网站通过阻止 iframe 来防御点击劫持,并且 XmlHttpRequest 不会“执行”页面。我需要它来可靠地为所有站点工作。

标签: javascript firefox firefox-addon settimeout xul


【解决方案1】:

在我使用 Firefox 开发的经验中,我发现在某些情况下,各种元素的初始化代码就像是异步的一样。换句话说,当你完成执行时

var newBrowser = window.document.createElement('browser');
newBrowser.setAttribute('flex', '1');
newBrowser.setAttribute('type', 'content');
cacheFrame.insertBefore(newBrowser, null);

,您的browser 可能实际上还没有准备好。当您添加延迟时,事物有时间进行初始化,因此它们可以正常工作。此外,当您执行动态创建browser 元素之类的操作时,您可能会做一些以前很少有人尝试过的事情。换句话说,这听起来像是 Firefox 中的一个错误,而且可能不会引起太多关注。

您说您正在使用onLocationChange,以便知道何时添加load 侦听器。我猜你正在将load 监听器添加到contentDocument,因为你提到了它。您可以做的是将load 侦听器添加到browser 本身,就像使用iframe 一样。如果我更换

newBrowser.addProgressListener(listener);

newBrowser.addEventListener("load", function(e) {
  console.log('got here! ' + e.target.contentDocument.location.href);
}, false);

然后我会收到每个browser 的通知。

【讨论】:

  • 感谢您的回答。不幸的是, newBrowser.addEventListener('load', f) 不起作用 - f 永远不会被调用。我还尝试在我的应用程序开始时立即创建一堆浏览器并稍后将侦听器绑定到它们,以解决异步问题。这不起作用,这让我认为这不是“浏览器已准备好”的问题。发生的另一件非常奇怪的事情是,如果我在 setTimeout 中包含对侦听器变量的赋值,它再次不起作用!
  • 如果您实际使用的是newBrowser.addEventListener('load', f),那么您将缺少最后一个参数。我用你的代码试过这个,它对我有用。如果没有,则发布您的新代码,我们可以看看发生了什么。
  • 啊哈,这个参数其实应该是true(默认是false)。谢谢!
猜你喜欢
  • 2014-08-23
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多