I have created a loading screen plugin. The scenario is that i am doing page navigation using ajax loading. So before loading a page using ajax, i would show an loading screen using the code $('body).loadingMask('show') and once the page is loaded completely loaded, i would remove the loading screen using the code $('body').loadingMask('hide).
The problem is that, there is some delay in retrieving the target dom element inside the plugin.
This is the general structure of the code
$('body').loadingMask('show');
$.ajax({
url : 'views/next.html',
async : false,
success : function(content, textStatus, jqXHR) {
$('body').append(content);
},
error : function(content, textStatus, jqXHR) {
throw "Unable to load template. Please check the path and name of the template"
}
});
$('body').loadingMask('hide');
The problem is that , inside the show function of the loadingMask plugin, There is a delay in retrieving the target dom element(i.e body) . So pratically, the code $('body).loadingMask('show') runs only after the ajax page is finished loading.
In order to make it work , i have added a time delay. Which seems to work fine.
This is the modified code
$('body').loadingMask('show');
setTimeout(function(){
$.ajax({
url : 'views/next.html',
async : false,
success : function(content, textStatus, jqXHR) {
$('body').append(content);
},
error : function(content, textStatus, jqXHR) {
throw "Unable to load template. Please check the path and name of the template"
}
});
},500);
$('body').loadingMask('hide');
Now i can see the loading screen, while the page loads.
If you remove async:false you can call your plugin withing the ajax success, right after the content gets added.
async:false is deprecated and often leads to unforeseen problems
$('body').loadingMask('show');
$.ajax({
url: 'views/next.html',
success: function(content, textStatus, jqXHR) {
$('body').append(content).loadingMask('hide');
},
error: function(content, textStatus, jqXHR) {
/* likely need to remove maske here and add something to content to advise user*/
throw "Unable to load template. Please check the path and name of the template"
}
});
Related
I am trying to load multiple .js files through the GetScript method.
I need them to be loaded in series, meaning the first .js files needs to be fully loaded before going to the next one.
Question 1: I was using the code below, but found that this becomes quite messy when the amount of js files increase. Is there a more clear way of loading multiple .js files?
Also, I've found that function( data, textStatus, jqxhr ) is a callback function that is executed when the getScript request succeeds. The parameters (data, textStatus, jqxhr) can be used in the funtion, where: data is the data from the .js file, textStatus is the status of the request and jqxhr is a XMLHttpRequest object.
Question 2: Why is the parameter textStatus used as a callback? Using it in this function will always set it to Success, right?
Question 3: When I only want to execute the next getScript, i could just leave out the parameters and write: jQuery.getScript("url.min.js", function() { Correct?
jQuery.getScript("//url1.com/file1.js", function(data, textStatus, jqxhr) {
jQuery.getScript("//url2.com/file2.js", function(data, textStatus, jqxhr) {
jQuery.getScript("//url3.com/file3.js", function(data, textStatus, jqxhr) {
jQuery.getScript("//url4.com/file4.js", function(data, textStatus, jqxhr) {
});
});
});
});
Thank you.
I was using the code below, but found that this becomes quite messy when the amount of js files increase. Is there a more clear way of loading multiple .js files?
You could DRY it up a little by recursively iterating through an array of URLs, assuming that no further processing is required in the callback. Something like this:
function getScript(arr, i) {
i = i || 0;
jQuery.getScript(arr[i], function() {
i++;
arr.length > i && getScript(arr, i);
});
}
getScript(['//url1.com/file1.js', '//url2.com/file2.js', '//url3.com/file3.js', '//url4.com/file4.js']);
Why is the parameter textStatus used as a callback? Using it in this function will always set it to Success, right?
It follows the same pattern as other jQuery AJAX methods, you're right that in this case it will always be a successful response.
When I only want to execute the next getScript, i could just leave out the parameters and write: jQuery.getScript("url.min.js", function() { Correct?
Yes
I would like to give a high level explanation of what's my issue because I can't put up complete code which is too complex.
I have a button. when I click on the button, it pulls data from fb parses it and adds it to the page. Now after it is loaded to then page.. I want to run a script on the loaded content. I am running the script after the data is parsed but somehow it shows that element is not loaded by the time script started running. can some one throw some light.
$("somebutton").on("click",function(){
LoadAndParseFbData();
});
function LoadAndParseFbData(){
//loaded the json, parsed it and added to the page.
anotherScript();
}
function anotherScript(){
// this has some script related to data which is loaded dynamically by parsing json.
}
This is what i am trying on high level. please help thanks :)
$("somebutton").on("click",function()
LoadAndParseFbData();
});
function LoadAndParseFbData(){
FB.api(path, method, params, function(){
//loaded the json, parsed it and added to the page.
anotherScript();
});
}
function anotherScript(){
// this has some script related to data which is loaded dynamically by parsing json.
}
Run anotherScript() from within the ajax success callback:
$J.ajax({
url: url2,
type: "post",
data: { data: "yourdata", },
success: function (data, textStatus, jqXHR) {
anotherScript();
},
error: function(jqXHR, textStatus, errorThrown) {
/*error handling code here*/
}
});
I am using jQuery ajax to render an HTML page which also contains javascript functions.
my code is:
function ChartBook() {
$.ajax({
url: '/Charts/ChartBook',
dataType: 'html',
id: 1,
traditional: true,
type: 'GET',
success: function (content) {
$(document.body).empty();
$(document.body).html(content);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('An unexpected error occured.');
}
});
}
The page Chartbook contains a function "GetChartData()".
It runs fine, but when I call another page in same manner, The Chartbook page is now not in the body, but I can still get alert message from function "GetChartData".
How can scripts be still there, while I have removed the page from html body with $(document.body).empty()?
EDIT:
Another problem is that, if I recall the "Chartbook" page and return to the previous page, The alert message comes twice from the function "GetChartData()". the number of alert message increases each time I load Chartbook page and return to previous page.
The scripts are usually placed on top of the body in a header section. Therefore they will not be removed by $(document.body).empty(); which you could also write as $('body').empty();.
Doesn't matter if you remove all html they are still in DOM check this
This is my first time using AJAX. I'm trying to load one of my pages when a link is clicked (I know I can just do <a href="something.html"> but I am doing it just for the sake of using AJAX, and ran into an issue where my page loads but the javascript of the page doesn't. Is this a normal AJAX consequence? I'm guessing it has to do with dataType: html? Here's my code:
function getContent(filename) {
$.ajax({
url: filename,
type: "GET",
dataType: "html",
beforeSend: function(){
$('html').html('<img src="../images/loading.gif">');
},
success: function (data, textStatus, xhr) {
if (filename == "second.html") {
setTimeout(function (){
$('html').html(data);
}, 2000);
} else {
$('html').html(data);
}
},
error: function(xhr, textStatus, errorThrown) {
$('html').html(textStatus);
}
});
}
Can you check chrome's network monitor? First off, does anything get a 404? Is the file literally second.html? If so then there shouldn't be path issues. Next what is the "response" that appears for that item? Does that response look ok?
Next, why don't you try moving the JS from head into the body for the second page? JS should always be right before the closing body tag for performance reasons. Also, there may be an issue with JS being in head and it not getting executed for that reason.
You should be able to load anything on your domain without any issues via AJAX, but there are path issues to watch out for.
This is because the ajax page is only returning rendered content, but does not run like a normal page would. You can use PHP on the ajax page for example, the server renders it and then sends it through, because PHP is pre-render, javascript runs after the page is rendered, as far as I know.
I've got the following code that shows a lightbox 'please wait' box, then does a synchronous ajax request which removes the lightbox when it finishes. Works fine everywhere else, but in IE, the lightbox doesn't show. The Ajax request works fine, but it just seems to ignore the lightbox.
The showLightbox function just does that, show a modal lightbox with the passed in text.
showLightbox("Please Wait");
$.ajax({
async: true,
dataType: 'json',
type: 'GET',
url: checkValidUrl,
data: submitData,
error: function(request, textStatus, errorThrown) {
valid = false;
},
success: function(data, textStatus) {
valid=true;
},
complete: function(request, textStatus) {
hideLightbox();
}
});
If I make the ajax requst async it works fine, but I need it to be synchronous because this is a validation method.
Update: Also, if I wrap the whole ajax request in a setTimeout it also works in IE, but that is asynchronous too
Update 2: I just replaced the lightbox with a simple div and did a jQuery .show() on beforeSend and .hide() on complete, and it didn't show that either, so it doesn't seem to have anything to do with the lightbox. If I whack an alert() immediately after showLightbox() it does show the lightbox
My guess is that IE either is too busy doing the request to show the lightbox or that it thinks it's supposed to stop to do the request. Try adding the showLightbox() function to the $.ajax function itself, to the beforeSend option.
$.ajax({
async: true,
dataType: 'json',
type: 'GET',
url: checkValidUrl,
data: submitData,
beforeSend: showLightbox(),
error: function(request, textStatus, errorThrown) {
valid = false;
},
success: function(data, textStatus) {
valid=true;
},
complete: function(request, textStatus) {
hideLightbox();
}
});
In your ajax call, you need to call the lightbox functionality again. I used Lytebox, so it may be different for you.
$j.post("kitchen.php", $j("#post_form").serialize(),function(result) {
//xmlhttp.open("GET","ajax_test.php",true);
//xmlhttp.send();
$j('#grab_kitchen').attr({'disabled' : 'false'});
$j('#grab_kitchen').removeAttr('disabled');
$j('#Output').fadeIn(500);
$j('#Output').html(result);
$j("body").css("cursor", "auto");
// add there your lytebox function to work
initLytebox();
});
This smells funny.
Firstly, I can't think of any good reason for using a synchronous request -- doing so locks the user's browser until the response is returned. It's a terrible user experience which would make most users think your website is killing their browser.
Secondly, you say you're doing this for validation? Any user who is malicious enough to try to alter a form while they wait for the asynchronous response would also be smart enough to just change your "async: false" to "async: true". Remember that all validation on the client side is only there for the benefit of the user, and all proper validation should be done server-side. I don't see why you'd need to do things this way.
Perhaps you should show the lightbox, and then do a setTimeout before you actually begin the synchronous request. I suspect that IE doesn't render your DOM changes until it gets control back from your JS function, and that doesn't happen until after the ajax request, and the box is hidden again. Give it a chance to render the lightbox, and then start your ajax request.
showLightbox("Please Wait");
setTimeout(function() {
$.ajax({
async: false,
dataType: 'json',
type: 'GET',
url: checkValidUrl,
data: submitData,
error: function(request, textStatus, errorThrown) {
valid = false;
},
success: function(data, textStatus) {
valid=true;
},
complete: function(request, textStatus) {
hideLightbox();
}
});
}, 100);
I have the same exact issue.
http://www.precisehomebuilders.com/kitchen-remodeling
There is a button at the bottom of the page that grabs more photo galleries, which works.
Here's the thing: if I do a "save as" after the ajax call and reload it, then it totally works. There's just something about grabbing lightbox items through ajax.