令人震惊的奇怪 IE 9 Javascript bug:更改文档标题会使后续代码执行
我完全不明白这一点。下面是一些适用于除 IE 9 之外的所有浏览器的 Javascript 代码。它是使用 ExternalInterface
从 Flash 影片中调用的,旨在如果影片的大小在内部发生变化,则在 DOM 中动态调整影片的大小
function vResizeFlash(swfId, ht) {
document.getElementById(swfId).height = "100%";
document.getElementById('flashContainer').style.height = ht + "px";
}
但如果我更改 document.title,它就可以正常工作:
function vResizeFlash(swfId, ht) {
// IE 9 won't run the rest of this function unless
// we go through the charade of changing the document title.
if (navigator.appName.indexOf("Microsoft") != -1) {
var docTitle = document.title.replace(/^(.+?)\s*$/,"$1");
document.title = docTitle + " ";
}
// Well-coded browsers begin here
document.getElementById(swfId).height = "100%";
document.getElementById('flashContainer').style.height = ht + "px";
}
在这里,我只需修剪 document.title
右侧的所有空格,然后向其中添加一个空格字符。突然以下几行被执行。注意:页面上还有其他 ExternalInterface
调用,即使在 IE 9 中,它们也都能正常工作,因此这不是 Flash/IE 9 问题。
我偶然发现了修复程序,因为我正在更改标题以显示函数参数(作为快速调试测试),只是为了确保函数正在运行。突然间,代码就起作用了。拿出来吗?不起作用。 100% 可重复。
有人知道为什么会发生这种令人震惊的行为吗?
更新
@c69 提出了问题:“也许是 IE9 的死代码删除器?”
我不知道这一点,所以我去谷歌搜索并找到这篇文章关于该主题,以及其他地方的一些讨论。然而,我对此了解不够,无法评估这将如何影响两行 Javascript 函数,特别是因为其中一行在页面上确实有一个引用(尽管它是通过 SwfObject 代码延迟加载的)。尽管如此,对于代码“优化器”来说,删除它认为不必要的代码行将是一个非常严重的错误,因为它不理解它们是如何调用的。如果它无法理解这些行是如何调用的,那么插入一行对 document.title 进行虚假更改会如何使该代码突然变得“必要”?
UPDATE 2
另一个难题 这可能与 IE 9 的兼容模式有关。该页面以 IE 9 的标准模式开始。
现在,如果我打开 IE 的兼容模式,
如果不使用上述 hack,问题就会消失。将其关闭,问题就会再次出现(如果不存在黑客)。
但是,当我尝试使用完全相同的 HTML(减去几个 JSP 标记)和仅包含调整大小代码和测试工具的精简 SWF 进行简单测试时,一切正常。然而,在这种情况下,根本不显示兼容性图标。
我们使用的是 Tomcat 6.0.32。我不知道我们正在使用任何特殊的标头,并且没有关于 IE 兼容性模式的元标记(在主应用程序或我的测试应用程序中)。
I don't understand this at all. Here is some Javascript code that works in every browser but IE 9. It is called from a Flash movie using ExternalInterface
, and is meant to dynamically resize the movie in the DOM if the size of the movie changes internally
function vResizeFlash(swfId, ht) {
document.getElementById(swfId).height = "100%";
document.getElementById('flashContainer').style.height = ht + "px";
}
But it works fine if I alter the document.title:
function vResizeFlash(swfId, ht) {
// IE 9 won't run the rest of this function unless
// we go through the charade of changing the document title.
if (navigator.appName.indexOf("Microsoft") != -1) {
var docTitle = document.title.replace(/^(.+?)\s*$/,"$1");
document.title = docTitle + " ";
}
// Well-coded browsers begin here
document.getElementById(swfId).height = "100%";
document.getElementById('flashContainer').style.height = ht + "px";
}
Here I simply trim any white-space from the right side of the document.title
, then add a single white-space character to it. Suddenly the following lines get executed. Note: there are other ExternalInterface
calls on the page, and all of them work fine, even in IE 9, so it's not a Flash/IE 9 problem.
I stumbled on the fix because I was altering the title to show the function arguments (as a quick debugging test), just to make sure the function was getting run. And suddenly the code worked. Take it out? Doesn't work. 100% reproducible.
Anybody know why this absolutely stupefying behavior takes place?
UPDATE
@c69 has posed the question: "Maybe its IE9's dead code remover?"
I didn't know about this, so I went and Googled and found this article on the topic, as well as some discussion of it elsewhere. I don't know enough about it to evaluate how this would affect a two-line Javascript function, however, especially since one of the lines does have a referent on the page (although it is late-loading through the SwfObject code). Still, it would be a pretty bad bug for a code "optimizer" to remove lines of code it deemed unnecessary because it doesn't understand how they are called. And if it did fail to understand how the lines are called, how does inserting a line making a bogus change to the document.title render that code suddenly "necessary"?
UPDATE 2
Another piece of the puzzle This may have something to do with IE 9's compatibility mode. The page starts out in IE 9's standards mode.
Now, if I turn on IE's compatibility mode,
the problem goes away without using the above hack. Turn it off, and the problem returns (if no hack present).
But when I tried to make a simple test using the exact same HTML (minus a couple of JSP tags) and a stripped down SWF that only contains the resize code and the tools to test, everything works fine. In that case, however, no compatibility icon is displayed at all.
We're using Tomcat 6.0.32. I'm not aware that we are using any special headers, and there are no meta tags regarding IE compatibility mode (in either the main app or in my test app).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
就像 InvertedSpear 提到的,检查你的文档类型,我最近在使用 IE9 时遇到了问题,其中大部分归结为文档类型标签触发了我不需要的兼容模式,元标签也是如此,所以它可能归结为你的元标签。
您也可以随时使用下面的链接强加工作兼容模式。
来自:http://evolpin.wordpress。 com/2011/02/25/ie9-compatibility-and-the-meta-tag/
我发现这确实是由 Microsoft 记录的...
http://msdn.microsoft.com/en-us/library/ cc288325(VS.85).aspx
“X-UA-Compatible 标头不区分大小写;但是,它必须出现在网页标题(HEAD 部分)中,位于除标题元素和其他元元素之外的所有其他元素之前。”
like InvertedSpear mentions, check your doc type out, i've had problems with IE9 recently and most of it boiled down to the Doc type tags triggering a compatability mode i didn't need, the same can be true of the meta tags so it might boil down to your Meta tags.
You can always impose a working compatibility mode using the links below too.
from: http://evolpin.wordpress.com/2011/02/25/ie9-compatibility-and-the-meta-tag/
I’ve discovered that this is indeed documented by Microsoft…
http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx
“The X-UA-Compatible header is not case sensitive; however, it must appear in the header of the webpage (the HEAD section) before all other elements except for the title element and other meta elements.”
每当我在任何语言中看到类似的事情发生时,都是因为其他代码存在错误。正如您所指出的,您的简单案例不会产生问题。尝试一次删除几行其他代码,直到问题消失 - 最后删除的代码应该包含问题。
干杯
Whenever I see something like this happen in any language it's because there is other code that has a bug. As you pointed out your simple case doesn't produce the problem. Try removing other code a few lines at a time until the problem disappears - the last removed code should contain the problem.
Cheers