I am calling a JS using jquery getScript().
Sometimes i could see that the files are already loaded (cached resource).
So,On refreshing the cached page is not removed and also the same file is loaded again.
Because of the multiple includes of the same file i am getting errors.
How to avoid that ?
$.getScript("http://localhost:8888//../../demo.js", function()
{
console.log('Script is loaded.');
});
By default, $.getScript sets the cache setting to false. Try setting it to true to see if this solves your problem:
$.ajaxSetup({
cache: true
});
Add the above before your call like:
$.ajaxSetup({
cache: true
});
$.getScript("http://localhost:8888//../../demo.js", function() { console.log('Script is loaded.'); });
directly from jquery docs:
Caching Responses
By default, $.getScript() sets the cache setting to false. This
appends a timestamped query parameter to the request URL to ensure
that the browser downloads the script each time it is requested. You
can override this feature by setting the cache property globally using
$.ajaxSetup():
$.ajaxSetup({ cache: true }); Alternatively, you could define
a new method that uses the more flexible $.ajax() method.
Examples: Example: Define a $.cachedScript() method that allows
fetching a cached script:
jQuery.cachedScript =
function( url, options ) {
// Allow user to set any option except for dataType, cache, and url options = $.extend( options || {}, {
dataType: "script",
cache: true,
url: url });
// Use $.ajax() since it is more flexible than $.getScript // Return the jqXHR object so we can chain callbacks return
jQuery.ajax( options ); }; // Usage $.cachedScript( "ajax/test.js"
).done(function( script, textStatus ) { console.log( textStatus );
});
I believe if it is cached the browser will not go make a new request for it, it will know to load the cached version, so you are good just firing off your $.getScript as you have it.
It may appear in the network tab of chrome developer tools again, but the time will be 0 and the Size (Content) value will say '(from cache)' This would be a good way to test what is actually going on.
Assuming your demo.js file contains at least one function or variable, you could check for presence before loading again:
if (typeof(your_variable) === "undefined") {
$.getScript("http://localhost:8888//../../demo.js", function() { console.log('Script is loaded.'); });
}
(where your_variable is the name of a function or variable inside demo.js)
Cashingvis good feature I solved multiple time loading js when I I load through jquery before. My issue was when I call a file loading by jquery I have a jquery file in that loading file now it loads only once so then events i now envoje only once. Thanks a lot have a nice day.
Related
I'm trying to load Cocoen through AJAX with JQuery. It works, but only some of the time.
I have this function to ajax load a javascript file, when it's needed:
jQuery.cachedScript = function( url, options )
{
// Allow user to set any option except for dataType, cache, and url
options = $.extend( options || {}, {
dataType: "script",
cache: true,
url: url
});
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return jQuery.ajax( options );
};
Then when I detect something with the "cocoen" class, it loads it in as needed like so:
if ($('.cocoen').length)
{
$.when(
$.cachedScript( "/includes/jscripts/cocoen/js/cocoen.min.js"),
$.cachedScript( "/includes/jscripts/cocoen/js/cocoen-jquery.min.js"),
$.Deferred(function( deferred ){
$( deferred.resolve );
})
).done(function(){
$('.cocoen').cocoen(); // image comparison slider
});
}
I don't know what causes it, but sometimes it seems to do the "done" function before it's properly loaded? As in chrome tools it says:
"Uncaught TypeError: $(...).cocoen is not a function". That is despite the network tab clearly showing both JS files for cocoen being loaded.
What am I doing wrong here? If I refresh, it then works. Seems random, but there must be something I'm not taking into account here.
As per jQuery documentation (https://api.jquery.com/jquery.getscript/) use more flexible $.ajax() method, but it doesn't work for me described in here (jQuery cannot load plugin file using ajax before calling the plugin function, thus, gives kind of weird result)
By default, $.getScript() sets the cache setting to false. This
appends a timestamped query parameter to the request URL to ensure
that the browser downloads the script each time it is requested. You
can override this feature by setting the cache property globally using
$.ajaxSetup():
$.ajaxSetup({
cache: true
});
But I need to cache few of the contents not all.
Alternatively, you could define a new method that uses the more
flexible $.ajax() method.
It didn't work for me as it doesn't guarantee loading files in a sequence.
Now what is the best solution for this situation?
$.getScript({
url: "foo.js",
cache: true
})
Supported on jQuery 1.12.0 or later
use $.ajax with dataType: 'script' and cache: true.
$.ajax({
cache: true,
url: 'foo.js',
dataType: 'script', // optional, can omit if your server returns proper contentType for js files.
success: function () {
console.log('Hello World!');
}
});
This assumes your server is responding with the headers required for the browser to cache the file.
What is the correct way to extend jQuery's getScript method to enable cache only inside that function for the ajax request?
I need to use this in my application to avoid unnecessary request for various scripts. Also is it correct to override this method or should I name the new function differently.
What I came up with is
jQuery.getCachedScript = function( url, callback, options ) {
// Allow user to set any option except for dataType, cache, and url
options = $.extend( options || {}, {
dataType: "script",
cache: true,
url: url,
success: callback
});
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return jQuery.ajax( options );
};
using the example form https://api.jquery.com/jQuery.getScript/. Is it correct, and can I name this getScript to override the jQuery method.
Would it be preferred to instead of using cache: true (or additionally) to use a global array that stores the .js files URLs and check against it for every call. I wrapped all the javascript code in this files in a function that I can call with different arguments using the getScript callback.
I am experiencing an issue in jQuery when I do multiple jsonp requests, all with the same jsonpCallback function. It seems that only for the one of those the callback function is triggered. Are JSONP requests somehow overwriting each other?
Below an example of doing 2 jsonp request to github, and even though both firebug shows that both of them return, the callback function getName is only called for one of them:
function getName(response){
alert(response.data.name);
}
function userinfo(username){
$.ajax({
url: "https://api.github.com/users/" + username,
jsonpCallback: 'getName',
dataType: "jsonp"
});
}
users = ["torvalds", "twitter", "jquery"]
for(var i = 0; i < users.length; i++){
userinfo(users[i]);
}
Your request fired only once because of how jsonp works.
Jsonp means adding a script tag to the page from an outside domain to get around Cross-Site Scripting protections built into modern browsers (and now IE6 and 7 as of April 2011). In order to have that script interact with the rest of the script on the page, the script being loaded in needs to call a function on the page. That function has to exist in the global namespace, meaning there can only be one function by that name. In other words, without JQuery a single jsonp request would look like this:
<script>
function loadJson(json) {
// Read the json
}
</script>
<script src="//outsidedomain.com/something.js"></script>
Where something.js would look like this:
loadJson({name:'Joe'})
something.js in this case has a hard-coded callback to load the JSON it carries, and the page has a hard-coded loadJson function waiting for scripts like this one to load and call it.
Now suppose you want to be able to load json from multiple sources and tell when each finishes, or even load JSON from the same source multiple times, and be able to tell when each call finishes - even if one call is delayed so long it completes after a later call. This hard-coded approach isn't going to work anymore, for 2 reasons:
Every load of something.js calls the same loadJson() callback - you have no way of knowing which request goes with which reply.
Caching - once you load something.js once, the browser isn't going to ask the server for it again - it's going to just bring it back in from the cache, ruining your plan.
You can resolve both of these by telling the server to wrap the JSON differently each time, and the simple way is to pass that information in a querystring parameter like ?callback=loadJson12345. It's as though your page looked like this:
<script>
function loadJson1(json) {
// Read the json
}
function loadJson2(json) {
// Read the json
}
</script>
<script src="//outsidedomain.com/something.js?callback=loadJson1"></script>
<script src="//outsidedomain.com/somethingelse.js?callback=loadJson2"></script>
With JQuery, this is all abstracted for you to look like a normal call to $.ajax, meaning you're expecting the success function to fire. In order to ensure the right success function fires for each jsonp load, JQuery creates a long random callback function name in the global namespace like JQuery1233432432432432, passes that as the callback parameter in the querystring, then waits for the script to load. If everything works properly the script that loads calls the callback function JQuery requested, which in turn fires the success handler from the $.ajax call.
Note that "works properly" requires that the server-side reads the ?callback querystring parameter and includes that in the response, like ?callback=joe -> joe({.... If it's a static file or the server doesn't play this way, you likely need to treat the file as cacheable - see below.
Caching
If you wanted your json to cache, you can get JQuery to do something closer to my first example by setting cache: true and setting the jsonpCallback property to a string that is hardcoded into the cacheable json file. For example this static json:
loadJoe({name:'Joe'})
Could be loaded and cached in JQuery like so:
$.ajax({
url: '//outsidedomain.com/loadjoe.js',
dataType: 'jsonp',
cache: true,
jsonpCallback: 'loadJoe',
success: function(json) { ... }
});
Use the success callback instead..
function userinfo(username){
$.ajax({
url: "https://api.github.com/users/" + username,
success: getName,
dataType: "jsonp"
});
}
$(function() {
function userinfo(username){
var XHR = $.ajax({
url: "https://api.github.com/users/" + username,
dataType: "jsonp"
}).done(function(data) {
console.log(data.data.name);
});
}
users = ["torvalds", "twitter", "jquery"];
for(var i = 0; i < users.length; i++){
userinfo(users[i]);
}
});
Not sure but the response I get from that call to the github API does not include gravatar_id.
This worked for me:
function getGravatar(response){
var link = response.data.avatar_url;
$('#list').append('<div><img src="' + link + '"></div>');
}
I have a very large javascript file I would like to load only if the user clicks on a certain button. I am using jQuery as my framework. Is there a built-in method or plugin that will help me do this?
Some more detail:
I have a "Add Comment" button that should load the TinyMCE javascript file (I've boiled all the TinyMCE stuff down to a single JS file), then call tinyMCE.init(...).
I don't want to load this at the initial page load because not everyone will click "Add Comment".
I understand I can just do:
$("#addComment").click(function(e) { document.write("<script...") });
but is there a better/encapsulated way?
Yes, use getScript instead of document.write - it will even allow for a callback once the file loads.
You might want to check if TinyMCE is defined, though, before including it (for subsequent calls to 'Add Comment') so the code might look something like this:
$('#add_comment').click(function() {
if(typeof TinyMCE == "undefined") {
$.getScript('tinymce.js', function() {
TinyMCE.init();
});
}
});
Assuming you only have to call init on it once, that is. If not, you can figure it out from here :)
I realize I am a little late here, (5 years or so), but I think there is a better answer than the accepted one as follows:
$("#addComment").click(function() {
if(typeof TinyMCE === "undefined") {
$.ajax({
url: "tinymce.js",
dataType: "script",
cache: true,
success: function() {
TinyMCE.init();
}
});
}
});
The getScript() function actually prevents browser caching. If you run a trace you will see the script is loaded with a URL that includes a timestamp parameter:
http://www.yoursite.com/js/tinymce.js?_=1399055841840
If a user clicks the #addComment link multiple times, tinymce.js will be re-loaded from a differently timestampped URL. This defeats the purpose of browser caching.
===
Alternatively, in the getScript() documentation there is a some sample code that demonstrates how to enable caching by creating a custom cachedScript() function as follows:
jQuery.cachedScript = function( url, options ) {
// Allow user to set any option except for dataType, cache, and url
options = $.extend( options || {}, {
dataType: "script",
cache: true,
url: url
});
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return jQuery.ajax( options );
};
// Usage
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
console.log( textStatus );
});
===
Or, if you want to disable caching globally, you can do so using ajaxSetup() as follows:
$.ajaxSetup({
cache: true
});