2012-07-24 48 views
0

我正在做一些简单的更改使用javascript到HTML元素已经存在,当页面服务(如更改div元素的背景图像,添加ID等)。这当然在IE8以外的每个浏览器都可以正常工作,其中更改似乎并未反映在DOM中,所以当我在JS运行后解析dom时,无法找到我正在查找的元素。该页面由头文件中的2个JavaScript文件构成,1是外部第三方脚本,我无法控制,但是添加了ids和背景图像。第二个是在第一个之后被调用的mine,并且正在解析文档以寻找具有新ID的特定元素。两者都是外部脚本,并且不在HTML源代码中内联。IE8的DOM不反映JS的变化

从我可以告诉它可以:

  • 的竞争条件,2级外部的Javascript运行1改变按钮和添加的识别码与其他被解析DOM寻找特定的元素,并为他们“再在同一时间运行第二从未找到的元素
  • IE8不正确刷新DOM已经作了修改

我的JS在头第一JS之后调用,所以你会认为阻塞不会c

  • 我已经尝试添加类的身体迫使DOM的刷新我的代码之前:澳洲英语我JS运行

    事情我已经尝试过的比赛条件和元素将是可用运行

  • 我已经使用IE8开发人员工具,并且ID和元素不存在,但是如果我刷新几次,它们会奇迹般地出现(此时页面已经完全加载并且可以完全与其交互)

有什么想法?

谢谢!

回答

1

要记住的一件事是,当您创建多个<script>标签时,您不能保证它们加载的顺序,并且取决于它们的构建方式 - 它们通常会在它们一开始就开始处理加载。

所以,如果你是其中一个本地文件,一个文件到一个CDN,比如:

<script type="text/javascript" 
     src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> 
</script> 
<script type="text/javascript" src="/js/my_script.js"></script> 

你必须要考虑到的是,CDN文件,通常远远快交货比你的托管文件。在上面这种情况下,这可能是件好事 - 因为jQuery在你的脚本之前被加载到页面中可能是理想的 - 但是如果你加载了不同的第三方脚本,这可能依赖于DOM中存在的某些元素您的脚本负责创建,您的脚本可能无法及时创建它们。

想象一下这样的情景:

<script type="text/javascript" src="https://someurl/somelib.js"> 
    // This script parses the DOM and applies alterations to certain items 
</script> 
<script type="text/javascript" src="/js/my_script.js"> 
    // This script creates the DOM elements the other script is supposed to alter 
</script> 

你的页面将只工作,如果本地文件,/js/my_script.js,首先加载 - 因为其他的文件正在从一个专用的CDN服务这是不大可能的。

当两个文件都被本地提供的,比如这是更糟:

<script type="text/javascript" src="/js/my_relied_upon_script.js"></script> 
<script type="text/javascript" src="/js/my_reliant_script.js"></script> 

在这种情况下,这一切都取决于你的本地Web服务器是如何发生的处理HTTP请求,以确定发生了什么以什么顺序。

所以 - 到解决方案:

1)让你的脚本中的所有等待documentonready事件激发。因为这个事件只发生在文档完全加载(包括任何其他需要完全加载其元素的HTTP请求,如脚本,图像等)时 - 您可以保证脚本至少会等到完整的DOM加载。

2)使下级脚本等待触发事件。

使用jQuery,一个例子可能是类似以下内容:

// Script #1 
$(document).bind('ready', function() { 
    $('#NeedsBackground').css({ background: 'url(/gfx/bg.png)' }); 

    var $wrapper = $('<div />').addClass('wrapper'); 
    $('#NeedsWrapper').wrap($wrapper); 

    // Here's the magic that enforces loading. 
    $(document).trigger('Script1Finished'); 
}); 

// Script #2 
$(document).bind('Script1Finished', function() { 
    $('.wrapper').css({ border: '1px solid #000' }); 
}); 

现在 - 请记住,上面的转化是相当可怕的,而不是你想做的事(如内联CSS等等) - 但他们举了一个例子。由于Script #2要求在运行之前存在.wrapper元素,因此需要确保在发生Script #1之后发生此元素。

在这种情况下,我们通过trigger完成了文档上的一个自定义事件,然后我们可以对此进行响应 - 而且我们只在DOM处于正确状态后才触发该事件。

+0

嗨,谢谢你提供的内容丰富的答案。 JS文件的顺序是这样的: – user1548054 2012-07-25 07:17:12

+0

嗨,谢谢你的信息答案。 JS文件的顺序是:JS_Which_adds_ids(在加载时调用)Js_which_parses_ids(称为onload)。有什么办法可以强制执行这个命令吗?或者这是纯粹依靠服务于请求的网络浏览器吗?不幸的是,使用JQuery不是这个项目的一个选项。 – user1548054 2012-07-25 07:23:25

+1

我想你可以让第一个脚本加载第二个脚本 - 但这很糟糕。你可以在http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml找到一个例子。你也可以考虑使用'setTimeout'循环来检查ID是否已经被创建,或者什么。如果您控制两个脚本,最好的解决方案可能是将它们混合/缩小为一个小文件 - 按照正确的顺序。这可能是最简单也是最安全的。 – 2012-07-25 18:26:44