在ajax调用之后加载脚本的位置在哪里?

假设您有一个简单的网页,可以动态加载如下所示的内容:

– main.html –

      $(function() { $.ajax({ type: 'get', cache: false, url: '/svc.html', success: function(h) { $('#main').html(h); } }); });    
loading...

并且它加载的页面在单独的文件中使用了一点Javascript:

– svc.html –

    
dynamically loaded content

注意脚本标记上的css属性 – 它表示属于脚本的样式表以及脚本将为我们加载的样式表。 这是脚本:

– plugin.js –

 var css = $('', { rel: "stylesheet", type: "text/css", href: $('script:last').attr('css') }); $('head').append(css); 

而且,最后,样式表,它只是为加载的inner div着色,以certificate它一切正常:

– plugin.css –

 #inner { border: solid 1px blue; } 

现在,您将注意到样式表的加载方式:我们查看$('script')并选择最后一个,然后我们获取css属性并将link项附加到文档的头部。

我可以访问/svc.html并运行javascript,加载我的样式表,一切都很酷 – 但是,如果我访问/main.html运行但无法在$('script')数组中找到plugin.js的加载$('script') (因此无法加载样式表)。 请注意,插件脚本确实运行,它只是看不到自己。

这是一个错误吗? jQuery AJAX方法的局限性? 不应该$('script')反映所有已加载的脚本?

*编辑*

在多次哭泣和咬牙切齿之后,我决定选择Kevin B的解决方案,但是,我无法让它工作,主要是因为plugin.js代码在scriptNode插入时运行,但在插件代码中,该节点尚未插入,因此在$('script')数组中不可用 – 所以我仍然是SOL。 我已将所有代码放在此处进行审核:

http://www.arix.com/tmp/loadWithJs/

将HTML添加到DOM的jQuery代码总是删除标记。 它运行它们然后扔掉它们。

这种行为的一个例外是当你使用“$ .load()”与允许你加载页面片段的hack时:

 $.load("http://something.com/whatever #stuff_I_want", function() { ... }); 

在这种情况下,脚本将被剥离, 不会被评估/运行。

您可以使用$ .ajax来获取html,自己去除脚本标记,附加内容,然后将脚本标记附加到dom中您想要的位置,以便它以您希望的方式执行。

 $.ajax({...}).done(function(html){ var htmlToAppend = html; // replace all script tags with divs htmlToAppend.replace(/ 

我的方式

在显示任何内容之前,在加载的实际页面上制作某种类型的加载器。 (关于这个,有很多关于jQuery的教程。)

关于这里的问题是你不能在每个页面重新加载jQuery。 只是主页面应该有jQuery调用:

  

或者只有一个页面可以调用它,只有孩子(是的,页面。从那里加载)将能够使用jQuery。

在我吸取教训之前,我曾经遇到过几次。 这可能不是您问题的完整答案,但可能是解决问题的开始。

好吧,经过多次努力,我已经将Kevin B的解决方案应用到了对其他人有用的插件中。 欢迎改进! (我应该把它放在github吗?)

– loadWithJs.js –

 // 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) { var target = this; var success = o.success; o.success = function (html) { // convert script tags html = $('
').append( html.replace(/<(\/)?script/ig, "<$1codex") ); // detach script divs from html var scripts = html.find("codex").detach(); // populate target target.html(html.children()); // loop through scripts and append them to the dom scripts.each(function () { var script = $(this)[0]; 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()) ); target[0].appendChild(scriptNode); }); if (success) success(); }; $.ajax(o); }; })(jQuery);

然后调用者可以这样做:

 $(function() { $('#main').loadWithJs({ type: 'get', cache: false, url: '/svc.html', success: function() { console.log('loaded'); } }); });