2011-11-27 55 views
0

previous SO post一个解决方案被发现动态加载页面嵌入<script>标签的问题。然而,这不是一个全面的解决方案,正如我所发现的。打破代码(请查看以前的帖子及其解决方案)的情况下,是一些看起来像这样:脚本在ajax调用之后加载到哪里? (还原)

- svc.html -

<script type="text/javascript" src="/plugin.js" css="/plugin.css"></script> 
<script type="text/javascript"> 
plugin_method(); 
</script> 

<div id='inner'> 
dynamically loaded content 
</div> 

其中plugin.js看上去和以前一样,但包含plugin_method的函数定义。

的问题似乎是,当脚本节点添加到文档:不立即执行

target[0].appendChild(scriptNode); 

的代码。如果(和上一篇文章一样)svc.html页面中只有一个脚本标记,则一切正常,但一旦有第二个脚本标记,插件中的$('script:last')不再指向正确的脚本,因此无法加载样式表。此外,第二个脚本标签的主体看起来在获取第一个脚本的代码之前执行,从而导致方法调用失败(因为该功能尚未定义)。

我发现一对夫妇的联系,这我在思索:

http://requirejs.org/docs/why.html http://unixpapa.com/js/dyna.html

想法吗?

回答

0

好了,答案是我们不能仅仅通过脚本列表迭代 - 我们需要将负载事件中递归,就像这样:

// inspired by Kevin B's suggestions 
// at: http://stackoverflow.com/questions/8234215/where-are-scripts-loaded-after-an-ajax-call 

(function ($) { 
    $.fn.loadWithJs = function (o) { 
     console.log(".loadWithJs - started"); 
     var target = this; 

     target.addScript = function (scripts, n, success) { 
      var script = scripts[n]; 

      var scriptNode = document.createElement('script'); 
      for (var i = 0; i < script.attributes.length; i++) { 
       var attr = script.attributes[i]; 
       $(scriptNode).attr(attr.name, attr.value); 
      } 
      scriptNode.appendChild(
       document.createTextNode($(script).html()) 
      ); 
      $(scriptNode).load(function() { 
       if (++n < scripts.length) 
        target.addScript(scripts, n, success); 
       else if (success) 
        success(); 
      }); 
      target[0].appendChild(scriptNode); 
     }; 

     var success = o.success; 
     o.success = function (html) { 
      // convert script tags 
      var h = $('<div />').append(
       html.replace(/<(\/)?script/ig, "<$1codex") 
      ); 
      // detach script divs from html 
      var scripts = h.find("codex").detach(); 
      // populate target 
      target.html(h.children()); 
      // start recursive loading of scripts 
      target.addScript(scripts, 0, success); 
     }; 

     $.ajax(o); 
    }; 
})(jQuery); 

*编辑*

好吧,那也行不通。如果我们在main.html末尾添加脚本标记,则会在第一个load事件触发(并且在脚本运行之前)之前将其添加到$('script')数组中,因此$('script:last')仍然是错误。 grr ...