为什么 window.external.menuArguments.setTimeout 不能通过 IE 上下文菜单工作
我正在为 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 在上面的测试代码中没有给我任何警报。
I'm writing a context menu extension for IE 6/7/8/9. I use window.external.menuArguments as current window object. This works fine for most common apis except setTimeout/setInterval. I tested it in IE 6-9, setTimeout doesn't work at all and setInterval causes memory exhausted in some cases. is there a work-around and am i missing any important tips in MSDN documents?
window.external.menuArguments.setTimeout(function() {
alert("setTimeout OK");
},100);
window.external.menuArguments.setInterval(function() {
alert("setInterval OK");
},100);
The disappointing IE doesn't give me any alerts in above test code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Microsoft 通过外部为您提供的环境是一个有趣的野兽。您实际上有两个窗口,第一个窗口包含
external
变量,而您刚刚右键单击进入的目标浏览器窗口是通过external.menuArguments
变量提供的。为了方便对话,我们将它们称为父窗口和子窗口,尽管它与window.open()
调用的关系不同。因此,在这种情况下,您有两个 setInterval/setTimeout 函数可供选择:
但是,尽管出于不同的原因,这两个函数都不会按您的预期执行。
第一个将执行 setTimeout,但它会传入一个函数引用,您的子窗口无法执行该函数引用,因为该函数本身是在父窗口中定义的。所以external.menuArguments无法调用
first
。第二个将执行 setTimeout,并且父
window
将引用second
,以便它可以在下一个事件循环中调用该方法。但 IE 的外部功能在退出之前不会从消息循环中提取所有消息。因此您的方法将排队,但代码将在第一个消息循环后退出。您可以通过
window.open('about:blank');
打开一个新窗口来防止父窗口立即退出,这将使窗口保持运行,直到弹出进程完全加载。在我的笔记本电脑上,这为我提供了大约 600 毫秒的工作间隔时间。我目前正在尝试设计一种 hack 来保持进程运行,同时不会像 for/while 循环那样死锁消息循环。我的猜测是 AJAX/FSO ActiveXObject 领域中的某些东西可以做到,但我还没有找到解决方案。我的情况需要父窗口进程永远执行,所以如果我找到解决方法,我会回复。
有趣的是,只要在 setTimeout 之后调用
alert()
,当间隔对我来说小于 10 毫秒时,就会运行 setTimeout 回调,因此在释放父窗口之前仅显示警报需要几毫秒过程。另一个痛苦是,出于遗留目的,JS 引擎是版本 7 或 8,因此父实例中没有 JSON 对象,这意味着如果您使用 external.menuArguments.JSON 对象,则对象序列化和反序列化在两个实例之间将具有不同的原型链反而。并且没有 Object.keys() 或任何其他现代语言的补充。
整个领域的文档非常非常稀疏,因此它通常是对任何有用的东西的反复试验。
The environment that Microsoft provides for you via externals is an interesting beast. You actually have two windows, the first window which contains the
external
variable and the target browser window you just right-clicked into is provided via theexternal.menuArguments
variable. For conversation's sake we'll call them the parent and child window, though it is not the same relationship as awindow.open()
call.So in this situation you have two setInterval/setTimeout functions to choose from:
But neither of these functions will execute as you would expect, though for different reasons.
The first one will execute setTimeout, but it will pass in a function reference that your child window cannot execute because the function itself is defined in the parent window. So external.menuArguments has no way to call
first
.The second one will execute setTimeout, and the parent
window
will have a reference tosecond
so it could call the method on the next event loop. But the externals feature to IE doesn't pump all messages from the message loop before exiting. So your method will be queued, but the code will quit after the first message loop.You can prevent the parent window from exiting immediately by opening a new window via
window.open('about:blank');
which will keep window running until the popup process is fully loaded. On my laptop this gives me about 600 milliseconds of interval time to work with.I'm currently trying to devise a hack to keep the process running while not dead-locking the message loop like what occurs with a for/while loop. My guess is something in the AJAX/FSO ActiveXObject realm will do, but I haven't found a solution yet. My situation requires the parent window process to execute forever, so I'll post back if I find a workaround.
Funny enough, just putting an
alert()
call after the setTimeout will run the setTimeout callback when the interval is less than 10 milliseconds for me, so just showing an alert takes a couple milliseconds before releasing the parent window process.The other pain is that for legacy purposes the JS engine is version 7 or 8, so no JSON object in the parent instance, which means object serialization and deserialization will have different prototype chains between the two instances if you use external.menuArguments.JSON object instead. And no Object.keys() or any other modern addition to the language.
Documentation as a whole for this realm is really, really sparse, so it's typically a trial and error experiment for anything useful.