I am loading external content into a div element using jquery.load() without a selector. If the content loaded has embedded JS, the JS works as expected. HOWEVER, if the content includes a script tag with src=path-to-js-code the js-code is not loaded.
Am I correct in this observation and if so is there a good solution other than embedding the JS in the loaded content?
EDIT :
A few clarifications and observations:
To load the content I am using
$("#DivId").load("path/to/content.php", CallbackFunction(response, status, xhr) {
error checking and post processing code
});
Changing the load code to:
$.get("path/to/content.php", CallbackFunction(response, status, xhr) {
error checking
$("#DivId").html(response);
post processing
});
Does not seem to change the behavior (more on the behavior below)
I have not tried parsing the response to retreive the script src and then using getScript().
Now more on the behavior...
Using Firefox, it seems that the external JS is loaded but only if it has been about 2 min from the last load. I do not see an attempt in Firebug unless the refresh is about 2m after the last load of the external JS. (weird). When I was making JS code changes and hitting refresh, it was not loading my new code and thus the original question.
So i will withdraw my question in light of this clarified behavior (2m caching?).
Thanks.
Both the .load() and .html() jQuery methods utilise the .innerHTML property. This won't execute scripts added with <script> tag. Use a regular AJAX call e.g. .get() then in the callback use .append() to add your HTML string and the scripts will run once it's parsed e.g.
$.get("path/to/content.php", function(response, status, xhr) {
// error checking
$("#DivId").append(response); // Any <script> tags in the response string will execute
// post processing
});
Thing is you need to make sure you're running trusted code if it's added by .append()
I was wondering you can get the script src in the response text of $.load method with regular expressions, then use $.getScript() method to load the script, maybe something like this:
$("#DivId").load("path/to/content.php", function(response, status, xhr) {
var regexp = new RegExp('script.*?src="(.*?)"'),
execresults = regexp.exec(response);
if(execresults.length > 1)
{
// the first result is the entire match including
// the 'script..src=', so abandon it
var matches = execresults.slice(1);
$.each(matches, function(){
$.getScript(this, function(){
// do something after load script
});
});
}
});
Hope this can help
This is the easy way to load an external JS to your jQuery
$.ajax({
type: "GET",
url: "path/to/content.php",
dataType: "script"
success:CallbackFunction(response, status, xhr)
});
Related
What exactly is the magic that jQuery does that causes execution of JS code inside script tags found inside an AJAX response?
For example, when not using jQuery AJAX like below, I see use of eval() is frequently described as as a way to do this:
Calling a JavaScript function returned from an Ajax response
Can scripts be inserted with innerHTML?
So eval does the magic of code execution in those cases. I do not see the use of eval in jQuery AJAX calls.
jQuery Magic
$("#form").submit(function() {
$.ajax({
type : "POST",
url : 'process_form.php',
data : $("#form").serialize(),
success : function(data) {
$("#main_page").load('main_page.php');
}
});
return false;
});
Here jQuery sets up an event (form submit) to where clicking submit on a form submits the form and then it AJAX-loads the DIV with information returned from main_page.php (That page contains update information + JS + jQuery) into main_page div element. But, not just that.
It also triggers and runs and executes any JS/jQuery code located inside the script tags of the ajax-loaded data without any use of eval that I can see
Question: How does it do that?
Note:
I am using some 3rd party proprietary AJAX library, which properly loads up the response into main_page div but then it does not run any JS/jQuery.
Note 2:
to be clear, there is no problem at all with the jQuery code in question. It works and executes whatever JS was in the main_page.php. The proprietary AJAX library that I use loads up the page but does not execute any AJAX in it. I want to figure out what makes it not execute the code when jQuery executes the code.
3rd Paty Library that does not trigger script tag code execution
Delving into the library I see this:
http_req.open(method, url, true);
if (method == "POST") {
http_req.setRequestHeader("Content-type",
"application/x-www-form-urlencoded");
http_req.setRequestHeader("Content-length", post_str.length);
http_req.setRequestHeader("Connection", "close");
http_req.send(post_str);
} else if (method == "GET") {
http_req.send(null);
}
Library is called using something like this event on a submit button:
onclick="process_form(..., url, 'main_page'...)"
It also has this:
var responseObj = new getObject(response);
responseObj.obj.innerHTML = http_req.responseText;
Full code surrounding the above:
http_req.onreadystatechange = function() {
if (http_req.readyState == 4 || http_req.readyState == "complete") {
if (response != "" && redir == "") {
if (response == "document") {
document.write(http_req.responseText);
} else {
//Update of innerHTML (but without triggering execution)
//of code found in <script> tags of http_req.responseText
responseObj.obj.innerHTML = http_req.responseText;
loadingObj.style.display = "none";
}
} else if (response != "" && redir != "" && response != "over") {
load_page(redir, "", response, "GET", "");
}
}
}
My guess is that it updates innerHTML but does not ...
add it into the DOM?
do eval?
do the magic?
What is the magic that jQuery possesses that the above library skips out?
Is there a way I can fix the library to cause it to execute the code found in response script tag?
Do you know that this callback is executed in your browser, right? This have nothing to do with your server response. It only executes WHEN your server gives you data back.
You can see proper documentation on XHR here https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
i hope i understand your question correctly:
success : function(data) {
$("#main_page").load('main_page.php');
}
this is the so called "success handler" - it is an event listener, that waits until the http response is received from the server. Javascript works a lot with callback functions which means, you call an action (like the ajax request) and once finished, it calls back another (often anonymous) function.
http://www.w3schools.com/js/js_events.asp
http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/
jQuery uses its own Deferred's to implement callbacks including for its ajax implementation. See the code here: https://github.com/jquery/jquery/blob/master/src/ajax.js
I have a site where I fetch additional HTML with AJAX (and jQuery). I parse this HTML with jQuery.parseHTML() and add the parsed HTML into my site with the function append(). I also use animations for displaying the new content.
Now I have some display problems which happen, when the parsed HTML is big. When I reload the same site everything is fine (maybe because the HTML is cached by the Browser). So I think the problem may be that the HTML was not totally parsed and prerendered by the browser. How can I check, when the fetched HTML is totally parsed and ready for rendering? (Note: I append the new HTML in way, that it is not directly visible to the user. Just the animation slides the new content in).
The function ready() does not seem to work. Thanks for your replies!
With ajax you can append .success or .done see http://api.jquery.com/jquery.ajax/
$.ajax({
url: "http://fiddle.jshell.net/favicon.png",
beforeSend: function( xhr ) {
xhr.overrideMimeType( "text/plain; charset=x-user-defined" );
}
})
.done(function( data ) {
if ( console && console.log ) {
console.log( "Sample of data:", data.slice( 0, 100 ) );
}
});
the done(function(data){} will contain all data and you can do what you want with it. It is called as soon as it has finished loading
I am looking for an equivalent to jquery's load() method that will work offline. I know from jquery's documentation that it only works on a server. I have some files from which I need to call the html found inside a particular <div> in those files. I simply want to take the entire site and put it on a computer without an internet connection, and have that portion of the site (the load() portion) function just as if it was connected to the internet. Thanks.
Edit: BTW, it doesn't have to be js; it can be any language that will work.
Edit2:
My sample code (just in case there are syntax errors I am missing; this is for the files in the same directory):
function clickMe() {
var book = document.getElementById("book").value;
var chapter = document.getElementById("chapter").value;
var myFile = "'" + book + chapter + ".html'";
$('#text').load(myFile + '#source')
}
You can't achieve load() over the file protocol, no other ajax request is going to work for html files. I have tried even with the crossDomain and isLocale option on without anything success, even if precising the protocol.
The problem is that even if jQuery is trying the browser will stop the request for security issues (well most browsers as the snippet below works in FF) as it allows you to load locale file so you could get access to a lot of things.
The one thing you could load locally is javascript files, but that probably means changing a lot of the application/website architecture.
Only works in FF
$.ajax({
url: 'test.html',
type: 'GET',
dataType: 'text',
isLocale: true,
success: function(data) {
document.body.innerHTML = data;
}
});
What FF does well is that it detect that the file requesting local files is on the file protocol too when other don't. I am not sure if it has restriction over the type of files you can request.
You can still use the JQuery load function in this context:
You would could add an OfflineContent div on your page:
<div id="OfflineContent">
</div>
And then click a button which calls:
$('#OfflineContent').load('OfflinePage.html #contentToLoad');
Button code:
$("#btnLoadContent").click(function() {
$('#OfflineContent').load('OfflinePage.html #contentToLoad');
});
In the OfflinePage.html you could have to have another section called contentToLoad which would display on the initial page.
$.get("progress.txt", null, function(data_aj){
if(data_aj.substr(0,14) == "<!-- MSG:: -->"){
$("#list").html("<li>"+data_aj+"</li>");
window.clearTimeout(timeOutId);
}else{
$("#list").html(data_aj);
}
});
I really have tried everything but can't figure out whats wrong. If I use alert(data_aj); it gives the desired output and just works fine but HTML(data_aj) just doesnt loads into a <ul> element #list using .html(). Can anyone tell me why?
Have you tried putting your code in a document ready, as your alert will fire fine but if your dom is not loaded then you cannot append to it. Also use .append() for lists not html
$(document).ready(function() {
$.get("progress.txt", null, function(data_aj){
if(data_aj.substr(0,14) == "<!-- MSG:: -->"){
$("#list").append("<li>"+data_aj+"</li>");
window.clearTimeout(timeOutId);
}else{
$("#list").append(data_aj);
}
});
});
Listen up...
$.get() is a shorthand for $.ajax().
So when you do this
$.get(uri, function(data){
//Your functionality
});
You're really doing this
$.ajax({
url: uri,
type: "GET",
success: function(data) {
//Your functionality
}
});
By default this returns the page as HTML. Or rather, by default, it first checks the MIME-type on the page, and if none is found, it returns HTML. As you are requesting a .txt file it will interpret it as a simple textfile. If you want to tell it what you would like to return (HTML), you can either do it in the MIME-type on the server page, or you could use $.getJSON().
An easy way to solve this is thus doing:
$.get(uri, function(data) {
//Your functionality
},
"html");
Which is the same as doing:
$.ajax({
url: uri,
type: "GET",
dataType: "HTML",
success: function(data) {
//Your functionality
}
});
Also it is not a good idea to use html() because you are replacing the existing html inside of your ul element every time you want to add an additional new node.
Try making use of:
$('#list').append('<li>' + data_aj + '</li>');
Basically you can just append the <li> to the <ul> itself.
Lastly make sure your dom has already been loaded by placing all your JQuery code into the
$(document).ready(function() {
//Your code...
});
Otherwise if your HTML is not fully loaded yet, your list might not exist yet so there is no way for JQuery to put some values into unexisting HTML.
So, I know how to use JS or jQuery, etc., to display a "Loading" message while content is loading. I have created a fairly large webapp with a number of JS dependencies and I want to display a "loading" message while all the scripts are loading.
My head tag has a number of <script src=…> tags in it and I want to display a loading message instantly when the user visits the page, and then remove it when all the scripts are loaded.
What's the best way to do this?
Then use $ajax function of jquery to download this javascript files and the add script element in head tag after downloading completes.
like this:
// display loading message here
$ajax("javascriptfile.js",function(file){
// attach downloaded file to head tag now
});
You probably need to lazy loading of the script. The last example from this Lazy Loading show to load .js via YUI. The code from that example is included below for your reference:
var HelloWorld = {
is_loaded: false,
lazyLoad: function(callback) {
var loader = new YAHOO.util.YUILoader();
loader.addModule({
name: "helloworld",
type: "js",
fullpath: "yui_ex/helloworld.js"
});
loader.require("helloworld");
if (callback) {
loader.onSuccess = callback;
}
loader.insert();
},
sayIt: function() {
var args = arguments;
HelloWorld.lazyLoad(function() { HelloWorld.sayIt.apply(HelloWorld, args); });
}
};
Note that you could possibly load the loading image initially and remove it in the callback function. Reading SO Question JQuery to load Javascript file dynamically, you could also use $.getScript() to do the same thing.
You could also find another example in this link