在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'); } }); });