IE7和IE8随机无法加载外部脚本

时间:2011-12-28 19:45:06

标签: javascript css dom internet-explorer-8 internet-explorer-7

一旦DOM准备好,我就会动态地将<link>元素添加到头部。但是,我在IE8和IE7中得到了不一致的结果(所有其他浏览器都很好)。

每次加载(缓存或未缓存)页面时,IE 7/8都会在样式表中删除一些CSS规则。 我的动态样式表中的1或2个将无法加载。它总是与IE倾向于忽略的1或2个样式表相同 - 即使开发人员工具栏将它们显示为添加到头部!

样式表本身在最终DOM中显示为<link>元素,但是它们的一些规则是而不是应用(尽管每次重新加载它们都没有任何问题)。< / p>

在我的职位上,我没有从<head>(CMS限制)编写代码的奢侈 - 我只能从正文中动态插入,这可能是问题。

更新:这是我使用的代码(位于<body>内)以插入样式表:

document.observe('dom:loaded', function() { // Using Prototype.js

// Add stylesheets
// addStylesheet('cite.css', 'head'); // Contains no webfont/@font-face rules
// addStylesheet('type.css', 'head'); // Contains webfont family name references*
// addStylesheet('flex.css', 'head'); // Responsive rules with @media queries
// addStylesheet('anm8.css', 'head'); // Some minor positional CSS for home page
// addStylesheet('gothic-cite.css', 'head'); // *Contains @font-face config
// addStylesheet('stag-cite.css', 'head'); // *Contains @font-face config

addStylesheet('all.css', 'head'); // Contains ALL content from above in 1 file

function addStylesheet(cssname, pos2)
{
    var th2 = document.getElementsByTagName(pos2)[0];
    var s2 = document.createElement('link');
    s2.setAttribute('type', 'text/css');
    s2.setAttribute('href', cssname);
    s2.setAttribute('media', 'screen');
    s2.setAttribute('rel', 'stylesheet');
    th2.appendChild(s2);
}

});

正如所建议的那样,即使我将所有规则合并到一个样式表中(我讨厌这样做),IE 7/8仍按照一些规则继续触发,页面显示不同。

作为进一步检查,我还从样式表中删除了所有@font-face和引用的font-family: "webfont-name"规则,并继续保持相同的行为。因此,我们可以排除将网页字体作为问题

您可以通过IE8访问以下内容并多次刷新/单击导航来查看异常。当IE8放弃这些样式时,似乎完全随机。但是,在本机构建的控制页面中,每次都会正确加载所有样式。

实时页面(有问题)

https://www.eiseverywhere.com/ehome/index.php?eventid=31648&tabid=50283

  1. 基于PHP的CMS在页面加载时打印出XHTML(与用户内容混合的模板内容)
  2. Prototype.js在页面加载时默认加载并初始化
  3. 在页面加载时解析CMS专有scripts.js文件
  4. 我的脚本在加载DOM时运行,基本上只用我想要的HTML替换body.innerHTML CMS fluff-HTML,然后将样式表添加到<head>
  5. 对于lte IE 8,CSS扩展插件(selectivizr.js,html5.js和ie-media-queries.js)通过条件注释在<body>内加载。不确定他们是否等待DOM:loaded ...
  6. CMS WYSIWYG编辑器将​​所有回车符转换为空<p>代码,导致<section>内的元素包含在已损坏的<p>代码中,以及在需要空格的地方创建额外的<p></p>标记。但是,只有lt IE 8似乎对此产生了影响,所以我添加了以下CSS规则来解决这个问题:

    :not(.ie7) p { display: none; }
    .ie7 p { display: inline; }
    article p { display: block !important; }
    
  7. 我应该注意,这里的外部样式表是从同一个域中提取的,但每次重新上传时,都会为该文件生成一个新的基于MD5的URL。我不确定以前的文件(或以前的文件)的先前版本是否仍然可用于以前的URL。但这不太可能是问题,因为新创建的all.css样式表仍然会丢弃从一开始就存在于文件中的规则。

  8. 控制页面(完美无瑕地工作)

    http://client.clevelanddesign.com/CD/IDG/CITE/home.html

    1. 纯XHTML文档 - 没有PHP。
    2. 使用jQuery而不是Prototype,用于IE8及以下版本。
    3. 页面加载时<head>中存在所有资源(样式表) - 无动态插入
    4. 对于lte IE 8,CSS扩展插件(selectivizr.js,html5.js和ie-media-queries.js)在本地初始化。
    5. 改述问题:

      您认为在Live页面上加载IE 7/8时,哪些差异可能导致样式触发?我个人怀疑是竞争条件问题,还是Prototype.js和其他CMS脚本混淆了(遗憾的是无法从页面中清除那些)。

      PS:我已经尝试过使用IE的createStylsheet()功能,但无济于事。

      更新 - 在IE8中工作/不工作的屏幕截图

      IE8:正确加载时的DOM代码: IE8: DOM code when loaded correctly

      IE8:正确加载 NOT 时的DOM代码: IE8: DOM code when NOT loaded correctly

2 个答案:

答案 0 :(得分:1)

我确切地确定了发生了什么,但仍然不知道触发器的原因:

每隔几页加载

selectivizr.js无法正确加载。

使用CSS3选择器的所有规则都需要在IE 7/8中应用该脚本。因此,当IE 7/8未正确加载selectivizr.js时,将忽略这些规则。这些规则当然包括webfont引用,以及错误的<p>显示属性。

为了提醒大家,在我的脚本替换<body>内容(包括该脚本之前)之前,这些帮助程序JS脚本正在正常加载(来自<body>内)初始页面加载参考)。因此,它有可能初始化两次(有人可以确认吗?)

问题是,在控制网站上,{1}} 总是在IE 7/8中正确加载。 CSS3帮助器js和媒体查询帮助js文件之间也没有已知的不兼容性(正确初始化时)。

我从页面中删除了selectivizr.js,并且在20次以上刷新后页面的加载方式完全相同。很高兴恢复一致性,我在IE 7/8中丢失了我的CSS3规则。

显然这就是有问题的js插件的工作方式:

  

根据W3C规范,网络浏览器应该丢弃样式   规则它不明白。这提出了一个问题 - 我们需要访问   到样式表中的CSS3选择器,但IE将它们抛弃。至   避免此问题使用a下载每个样式表   XMLHttpRequest的。这允许脚本绕过内部浏览器   CSS解析器并获得对原始CSS文件的访问权。

来源:http://www.css3.info/css3-pseudo-selectors-emulation-in-internet-explorer/

我可以尝试任何你可能拥有的建议的CSS3选择器插件;也许一个会加载更可靠,或者开销更少,因此与滞后相关的问题的空间更小。任何替代方案?

或者,也许我应该在之后将添加到第二次(在我的脚本替换正文内容之后)到selectivizr.js<head>中的其他地方1}}。 这些选项都不起作用 - 它们具有相同的结果

答案 1 :(得分:-1)

首先请允许我说我已经参与了多个计划,团队已经开始通过Javascript动态生成DOM,包括通过CORS远程加载脚本。

在3个不同的项目(以及每个项目中使用的不同方法)经过数月的努力之后,我们最终不得不面对IE7和IE8无法正确或一致地动态加载和处理外部脚本或CSS的事实。

我的建议是整合/组合PHP /服务器端的所有脚本,并作为单个文件提供,可以在客户端缓存。

作为补充说明,IE并非完全可以归咎于此。以正确的顺序下载,处理和渲染脚本/ css涉及巨大的复杂性,并且编程这个过程使得它在每个环境中都能很好地工作(webkit + mozilla + IE9 +)需要近乎专家级的知识和非常全面的测试。

在你的情况下,一个不好的“流程”的例子是,当我专门查看你的页面时,它会在屏幕“更新”之前简要地显示非CSS应用页面(太棒了!)并且CSS被拉入并应用。坏坏。

我注意到的其他问题通常是大量的httprequest。每个都需要DNS查找,缓存/过期检查(以及标题所指示的其他内容),以及随后的响应下载。在台式机上,这并不是那么明显,但在移动设备,平板电脑甚至是一些速度较慢/陷入困境的PC上,它尤其值得注意。

如果您在今天的浏览环境中构建一个Web应用程序并且只有一个小团队,那么最好是:

  1. 将CSS作为CDN中的单个可缓存文件提供服务,并将页面预先解析,预先迭代,预渲染的HTML块,最小化客户端JS处理(仅加载后绑定元素),或者
  2. 使用预先存在的客户端框架,如Sencha,SproutCore,YUI等。 - 他们为您构建了框架并修复了所有错误。
  3. 在我更改视图之前必须做两件事:IE8必须从一般用途中消失(低于10%),而“普通”移动设备需要有2个物理处理器核心。目前只有昂贵/高端型号才有双核处理器。

    另外值得注意的是,即使使用JIT JS编译器,速度最快的移动处理器仍然比JS性能的典型桌面慢10倍 - 直接与桌面相比,它将与Pentium 4或旧AMD竞争对手Athlon 64.