Internet explorer 为什么window.external.menuArguments.setTimeout不能通过IE上下文菜单工作

Internet explorer 为什么window.external.menuArguments.setTimeout不能通过IE上下文菜单工作,internet-explorer,settimeout,setinterval,Internet Explorer,Settimeout,Setinterval,我正在为IE 6/7/8/9编写上下文菜单扩展。我使用window.external.menuArguments作为当前窗口对象。这对于除setTimeout/setInterval之外的大多数常见API都很好。我在IE6-9中测试过,setTimeout根本不起作用,在某些情况下setInterval会导致内存耗尽。是否有解决方法,我是否遗漏了MSDN文档中的任何重要提示 window.external.menuArguments.setTimeout(function() { ale

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

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

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

微软通过externals为您提供的环境是一个有趣的野兽。实际上,您有两个窗口,第一个窗口包含外部变量,而您刚才右键单击进入的目标浏览器窗口是通过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无法首先调用

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

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

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

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

另一个问题是,出于遗留目的,JS引擎是版本7或8,因此父实例中没有JSON对象,这意味着如果改用external.menuArguments.JSON对象,对象序列化和反序列化将在两个实例之间具有不同的原型链。没有对象键或任何其他现代语言的补充


这个领域的文档总体上非常非常稀少,因此对于任何有用的东西,它通常都是一个试错实验。

您的代码使用什么类型的扩展?具体来说,它是显示窗口,还是立即关闭窗口的静默类型?我的第一个猜测是,它正在破坏并带走你的回电。如果您直接将脚本注入父窗口,例如,带有脚本标记的createElement是否有效?它是IE的上下文菜单扩展。我通过使用带有脚本标记的createElement将脚本直接注入父窗口来解决这个问题。window.external.menuArguments在动态更改当前窗口对象和文档对象时可能有许多限制。由window.external.menuArguments设置的事件(包括setTimeout/setInterval)和其他DOM事件(如window.external.menuArguments.document.body.AttacheEvents)将不会被激发。使用HTA为长时间运行的父进程解决了我的所有问题。特权跨域访问不仅对iFrame和弹出窗口都是永久性的,而且还使用最新的jvm/ie控件。我仍然在使用一个enternal menuArguments脚本,但它将json序列化到文件系统,hta在其中检查要处理的新文件。