什么时候执行JS脚本,如果它们加载了jQuery .html()函数?

时间:2014-07-24 08:21:37

标签: jquery ajax

我试图找出当使用.ajax() jQuery函数加载HTML + JS内容时执行JavaScript,并使用.html(content)插入内容。我读过有关domManip的内容,请阅读

我已经学到了很多东西,但是在脚本运行时却没有发现:

  1. 解析并插入HTML后jQuery会运行脚本吗? (所以我可以在JS中引用加载HTML中的每个DOM对象)
  2. jQuery会按照遇到的顺序运行脚本吗?使用src加载脚本时会发生什么?
  3. 例如,这是由.ajax()加载的HTML,然后插入.html()

    <p id="p1">Lorem ipsum...</p>
    <script type="text/javascript" src="file.js">
    <p id="p2">Dolorem...</p>
    

    在我的计算机上,在三个浏览器上,file.js我可以参考#p2,一切正常。

2 个答案:

答案 0 :(得分:2)

以非压缩形式查看jQuery 1.11.0的来源,很明显jQuery会检测脚本,并使用eval()执行。

引用domManip函数:

// Evaluate executable scripts on first document insertion
for ( i = 0; i < hasScripts; i++ ) {
    [...]
    if ( node.src ) {
        // Optional AJAX dependency, but won't run scripts if not present
        if ( jQuery._evalUrl ) {
            jQuery._evalUrl( node.src );
        }
    } else {
        jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
    }
    [...]
}

所以他们实际上会按照他们遇到的顺序执行。正如您所看到的,这仅适用于内联脚本。因此,在您的file.js示例中,我的初始答案的前一部分代表:

您可以引用p2的原因是,在插入HTML剪辑后,浏览器将发出第二个常规HTTP请求来加载文件。尽管如此,这是一个竞争条件,但是非常省略,因为第二个p的解析总是比从服务器加载另一个JavaScript文件更快。


下面的旧的和不正确的假设。

<击> 在我的opionion中,jquery将不运行任何插入的jquery脚本。浏览器会。因此,它们按插入顺序执行。

我的理由是<script>标签只是jquery的另一个DOM节点。它没有理由在那里寻找任何可执行的东西 - 这是JavaScript解析器的工作(它是浏览器的一部分)。

答案 1 :(得分:0)

我创建了两个文件:

js_test.html

<!DOCTYPE html>
<html>
  <head>
  <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
  </head>
  <body>
    <div id="div1"></div>
    <p id="clickable">Click!</p>
    <script type="text/javascript">

    $(document).ready(function(){
      $("#clickable").click(function(){
        $.ajax("js_test_insert.html").done(function(content){
          $("#div1").html(content);
        });
      });
    });

  </script>
  </body>
</html>

js_test_insert.html

<script type="text/javascript">
alert("Before.");
$("#inserted p").css("background-color","yellow");
alert("Middle."); 

$(document).ready(function(){
  alert("Inserted ready!");
});

</script>
<div id="inserted">
<p>Hello, World!</p>
</div>
<script type="text/javascript">
alert("After.");

function test() {
  alert("It should not run");
}

</script>

我在FF 18.0,Chrome 36.0和IE 11.0(也使用以前的IE仿真)上尝试过它,并且:

    点击
  1. p#clickable
  2. “你好,世界!”出现在“点击!”上方。
  3. 提醒“之前。”
  4. “你好,世界!”变黄了。
  5. 提醒“中间。”
  6. 警告“已插入就绪!” (我不明白为什么.ready()被执行
  7. 提醒“之后。”
  8. jQuery首先插入HTML,构建DOM,然后执行JS(按照外观顺序)。

    编辑:为什么.ready()被执行?因为事件仍然是,在'efect''(文件是,准备好的',所有时间,不是吗?) - 所以添加这个事件的新处理程序会导致立即执行处理程序。

    解决。