This seems to be a problem related to Safari only. I\'ve tried 4 on Mac and 3 on Windows and am still having no luck.
I\'m trying to load an external HTML file and
I ran into this where the scripts would load once, but repeat calls would not run the script.
It turned out to be an issue with using .html() to display a wait indicator and then chaining .load() after it.
// Processes scripts as expected once per page load, but not for repeat calls
$("#id").html("<img src=wait.gif>").load("page.html");
When I made them separate calls, my inline scripts loaded every time as expected.
// Without chaining html and load together, scripts are processed as expected every time
$("#id").html("<img src=wait.gif>");
$("#id").load("page.html");
For further research, note that there are two versions of .load()
A simple .load() call (without a selector after the url) is simply a shorthand for calling $.ajax() with dataType:"html" and taking the return contents and calling .html() to put those contents in the DOM. And the documentation for dataType:"html" clearly states "included script tags are evaluated when inserted in the DOM." http://api.jquery.com/jquery.ajax/ So .load() officially runs inline scripts.
A complex .load() call has a selector such as load("page.html #content"). When used that way, jQuery purposefully filters out script tags as discussed in articles like this one: https://forum.jquery.com/topic/the-load-function-and-script-blocks#14737000000752785 In this case the scripts never run, not even once.
Well I had the same problem that only seemed to happen for Firefox, and I couldn't use another JQuery command except for .load() since I was modifying the front-end on exisitng PHP files...
Anyways, after using the .load() command, I embedded my JQuery script within the external HTML that was getting loaded in, and it seemed to work. I don't understand why the JS that I loaded at the top of the main document didn't work for the new content however...
If you want to load both the HTML and scripts, here's a more automated way to do so utilizing both $(selector).load()
and jQuery.getScript()
. This specific example loads the HTML content of the element with ID "toLoad" from content.html
, inserts the HTML into the element with ID "content", and then loads and runs all scripts within the element with the "toLoad" ID.
$("#content").load("content.html #toLoad", function(data) {
var scripts = $(data).find("script");
if (scripts.length) {
$(scripts).each(function() {
if ($(this).attr("src")) {
$.getScript($(this).attr("src"));
}
else {
eval($(this).html());
}
});
}
});
This code finds all of the script elements in the content that is being loaded, and loops through each of these elements. If the element has a src
attribute, meaning it is a script from an external file, we use the jQuery.getScript
method of fetching and running the script. If the element does not have a src
attribute, meaning it is an inline script, we simply use eval
to run the code. If it finds no script elements, it solely inserts the HTML into the target element and does not attempt to load any scripts.
I've tested this method in Chrome and it works. Remember to be cautious when using eval
, as it can run potentially unsafe scripts and is generally considered harmful. You might want to avoid using inline scripts when using this method in order to avoid having to use eval
.
Tacking onto @efreed answer...
I was using .load('mypage.html #theSelectorIwanted')
to call content from a page by selector, but that means it does not execute the inline scripts inside.
Instead, I was able to change my markup so that '#theSelectorIwanted'
became it's own file and I used
load('theSelectorIwanted.html`, function() {});
and it ran the inline scripts just fine.
Not everyone has that option but this was a quick workaround to get where I wanted!
A other version of John Pick's solution just before, this works fine for me :
jQuery.ajax({
....
success: function(data, textStatus, jqXHR) {
jQuery(selecteur).html(jqXHR.responseText);
var reponse = jQuery(jqXHR.responseText);
var reponseScript = reponse.filter("script");
jQuery.each(reponseScript, function(idx, val) { eval(val.text); } );
}
...
});
$("#images").load(location.href+" #images",function(){
$.getScript("js/productHelper.js");
});