suppose you have a simple web page that dynamically loads content that looks like this:
- main.html -
you can use $.ajax to get the html, strip out the script tags yourself, append the content, and then append the script tag to the location in the dom where you want it so that it executes the way you want it to.
$.ajax({...}).done(function(html){
var htmlToAppend = html;
// replace all script tags with divs
htmlToAppend.replace(/<script/ig,"<div class='script'");
htmlToAppend.replace(/<\/script>/ig,"</div>");
// detach script divs from html
htmlToAppend = $(htmlToAppend);
var scripts = htmlToAppend.find(".script").detach();
// append html to target div
htmlToAppend.appendTo("#target");
// loop through scripts and append them to the dom
scripts.each(function(){
var $script = $(this),
scriptText = $script.html(),
scriptNode = document.createElement('script');
$(scriptNode).attr('css', $script.attr('css');
scriptNode.appendChild(document.createTextNode(scriptText));
$("#target")[0].appendChild(scriptNode);
});
});
I haven't tested this code, but it is based on code from history.js
Edit: here's a simpler solution more tailored for your needs:
$("#target").load(url,function(obj){
// get css attribute from script tag using the raw returned html
var cssPath = obj.responseText.match(/css="(.*)"/i)[1];
$('<link />', {
rel: "stylesheet", type: "text/css", href: cssPath
}).appendTo('head');
});
since .load() strips the script tags and then executes them, this will read the raw response text and get the css path from it, then add the link element.
I'm not entirely sure why it is handled this way.
Edit: see comment.
$.ajax({...}).done(function(html){
$("#target")[0].innerHTML = html;
});
The jQuery code that adds HTML to the DOM always strips out <script>
tags. It runs them and then throws them away.
An exception to that behavior is when you use "$.load()" with the hack that allows you to load a fragment of a page:
$.load("http://something.com/whatever #stuff_I_want", function() { ... });
In that case, the scripts are stripped and not evaluated/run.
My solution would be rather simple
Why not load the the files needed in main, on the first load all together? Then simply have a listener event. (Check if the content is simply loaded?)
The only solution for loading on demand...
You simply has to AJAX call the script file itself...
<script type="text/javascript">
$(function () {
$.ajax({
type: 'get',
cache: false,
url: 'svc.html',
success: function(response) {
if (response) { // If any response aka, loaded the svc.html file...
$('#main').html(response);
$.ajax({
url: 'plugin.js',
dataType: 'script',
success: function(reponse) {
// You can now do something with the response here even...
}
});
}
}
});
});
</script>
My way
Make some type of loader instead on the actual page on load before displaying anything. (Plenty of tutorials with jQuery around the web for this.)
ok, after many struggles, I've implemented Kevin B's solution into a plugin useful to others. Improvements welcome! (should I maybe put it in 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 = $('<div />').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);
then the caller can do:
$(function() {
$('#main').loadWithJs({
type: 'get', cache: false,
url: '/svc.html',
success: function() { console.log('loaded'); }
});
});
On of the problems here is that you CANNOT reload the jQuery in every page. Just the main page should have the jQuery call:
<script type='text/javascript' src='jQuery-url'></script>
Or only one page can call it and ONLY THE CHILDREN (yes, the pages .LOADed from there) will be able to use jQuery.
I've ran into that a few times before I learned my lesson. This might not be the entire answer for your problems but could be the beginning of solving them.