【问题标题】:why window.external.menuArguments.setTimeout doesn't work via IE context menu为什么 window.external.menuArguments.setTimeout 不能通过 IE 上下文菜单工作
【发布时间】:2011-10-26 10:26:27
【问题描述】:

我正在为 IE 6/7/8/9 编写上下文菜单扩展。我使用 window.external.menuArguments 作为当前窗口对象。这适用于除 setTimeout/setInterval 之外的大多数常见 API。我在 IE 6-9 中对其进行了测试,setTimeout 根本不起作用,并且 setInterval 在某些情况下会导致内存耗尽。是否有解决方法,我是否遗漏了 MSDN 文档中的任何重要提示?

window.external.menuArguments.setTimeout(function() {
    alert("setTimeout OK");
},100);
window.external.menuArguments.setInterval(function() {
    alert("setInterval OK");
},100);

令人失望的 IE 在上面的测试代码中没有给我任何警报。

【问题讨论】:

  • 您的代码使用什么类型的扩展?具体来说,它是显示一个窗口,还是立即关闭窗口的静默类型?我的第一个猜测是它正在破坏并取消您的回调。如果您将脚本直接注入父窗口(例如带有脚本标签的 createElement),它是否有效?
  • 它是 IE 的上下文菜单扩展。我已经通过带有脚本标签的 createElement 直接将脚本注入父窗口来解决这个问题。 window.external.menuArguments 可能对动态更改当前窗口对象和文档对象有很多限制。 window.external.menuArguments 设置的事件不会被触发,包括 setTimeout/setInterval 和其他 DOM 事件,如 window.external.menuArguments.document.body.attachEvent

标签: internet-explorer settimeout setinterval


【解决方案1】:

Microsoft 通过外部为您提供的环境是一个有趣的野兽。您实际上有两个窗口,第一个窗口包含 external 变量,而您刚刚右键单击进入的目标浏览器窗口是通过 external.menuArguments 变量提供的。为了对话,我们将它们称为父窗口和子窗口,尽管它与 window.open() 调用的关系不同。

所以在这种情况下,您有两个 setInterval/setTimeout 函数可供选择:

window.external.menuArguments.setTimeout(function first() { console.log('child'); }, 1);

window.setTimeout(function second() { external.menuArguments.console.log('parent'); }, 1);

但是这些函数都不会像您期望的那样执行,尽管原因不同。

第一个会执行setTimeout,但是它会传入一个你的子窗口不能执行的函数引用,因为函数本身是在父窗口中定义的。所以 external.menuArguments 没有办法调用first

第二个将执行 setTimeout,父 window 将引用 second,因此它可以在下一个事件循环中调用该方法。但是 IE 的外部功能不会在退出之前从消息循环中抽取所有消息。所以你的方法会被排队,但是代码会在第一个消息循环后退出。

您可以通过window.open('about:blank'); 打开一个新窗口来防止父窗口立即退出,这将保持窗口运行直到弹出进程完全加载。在我的笔记本电脑上,这给了我大约 600 毫秒的间隔时间。

我目前正在尝试设计一种技巧来保持进程运行,同时不会像 for/while 循环那样死锁消息循环。我的猜测是 AJAX/FSO ActiveXObject 领域中的某些东西会做,但我还没有找到解决方案。我的情况需要父窗口进程永远执行,所以如果我找到解决方法,我会回复。

很有趣,只要在 setTimeout 之后调用 alert() 就会在我的间隔小于 10 毫秒时运行 setTimeout 回调,所以在释放父窗口进程之前只显示一个警报需要几毫秒。

另一个痛苦是,出于遗留目的,JS 引擎是版本 7 或 8,因此父实例中没有 JSON 对象,这意味着如果使用 external.menuArguments,对象序列化和反序列化将在两个实例之间具有不同的原型链.JSON 对象。并且没有 Object.keys() 或该语言的任何其他现代添加。

这个领域的整个文档非常非常稀少,所以它通常是对任何有用的东西的反复试验。

【讨论】:

  • 事实证明,为长期运行的父进程使用 HTA 解决了我的所有问题。不仅 iframe 和弹出窗口的特权跨域访问成为永久的,而且它还使用最新的 jvm/ie 控件。我仍在使用一个 enternal menuArguments 脚本,但它将 json 序列化到 hta 检查要处理的新文件的文件系统。
猜你喜欢
  • 1970-01-01
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 2011-10-18
相关资源
最近更新 更多