I am looking for a way cache script with dynamically generated url I am currently using Octobercms that combines all scripts into one file on render I have seen in the past people using php but October cms uses blade the script I have looked at is this one
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
console.log( textStatus );
});
the problem I have is that the url the combined script is different on ever installation.
I have figured out how to stop the problem with the "Velocity is already loaded" error by using the following
$("#loader").load(href, function(){
delete jQuery.Velocity;
$.getScript( "http://yoursite.com/test/combine/b075f6a5b111b3375ecc553c0d813ee5-1534701438", function() {
// Call custom function defined
});
just need to figure out how to replace "http://yoursite.com/test/combine/b075f6a5b111b3375ecc553c0d813ee5-1534701438" as this alters any help with this part of the code would be great I have tried user2033464 code but when I console.log(path); after $.getScript I get "ReferenceError: path is not defined"
I have solved my problem as follows
var path= $("script[src]:eq(1)").attr('src'); //needs to be globle to work in getScript
$(document).ready(function() {
$("#loader").load(href, function(){
delete jQuery.Velocity; // stops Velocity reloading error
$.getScript( path, function() { // loads script into newly loaded page into existing page
// Call custom function defined
});
});
I hope the helps someone with similar problem thank user2033464 for your assistance
Related
I've already lost many hours trying to do something I think it is impossible.
I have a script with a source to a website and that source is a simple link like:
<script type='text/javascript' src='http://ads1.qadabra.com/t?asdasdasdasd'></script>
This script only runs while the document is loading and all my efforts to try to run it after the document has loaded were ruined.
I wonder if I can place the src tag inside the document, will it run after the document has loaded? That script loads a banner from that website and I want to load it x seconds after the page has totally loaded.
Does anyone has a solution to this? I have already asked several questions about this issue in the past few days but I can't get to a solution :/
Thanks in advance!
This problem is the same as mine but does not offer good solutionshttps://forums.digitalpoint.com/threads/how-to-load-the-advertising-banner-code-after-the-website-has-been-fully-loaded.2286973/
Using jQuery (i didn't test it):
$(document).ready(function(){
var delay = 5000;
setTimeout(
function(){
$.getScript( "ajax/test.js", function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
}, delay);
});
From the docs:
http://api.jquery.com/jQuery.getScript/
The callback is fired once the script has been loaded but not necessarily executed.
Our project contains many pages which has up to 20 tabs, each works with different scripts. All the script files are referenced in <head> and loads on the first page load. Now we have performance issue because there are too many scripts on the page loads on opening it (about 2k lines of JavaScript per tab). The matter is in much cases user needs to work with 2-3 tabs and as a result more than 60% of code becomes not used. So we need any scripts lazy-loading solution to ease the pages. As HTML for every tab is loaded on demand we can put <script> references in every tab that will provide a good working solution. But I'm prety sure including references not in <head> is a bad style.
So I wonder, is there any another solution? How such problems are solved in big projects like us? Any advice will be helpfull.
Thanks in advance!
jQuery has a great function for this sollution:
$.getScript("my_lovely_script.js", function(){
alert("Script loaded and executed.");
// here you can use anything you defined in the loaded script
});
This is by default not cached. I looked for a solution on the jQuery website it stated this solution for a cached script include.
jQuery.cachedScript = function(url, options) {
// allow user to set any option except for dataType, cache, and url
options = $.extend(options || {}, {
dataType: "script", //Note this
cache: true, //Enable caching
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("URL HERE").done(function(script, textStatus) {
console.log( textStatus );
});
I'm trying to dynamically insert and execute a couple of scripts, and I think I'm hitting a race condition where the second is trying to execute before the first is loaded.
The project I'm working on has an unusual requirement: I am unable to modify the page's HTML source. It's compiled into an app for localization purposes.
Therefore, I'm unable to insert <script> tags like I normally would to link in JavaScript files.
It turns out that the client wants to use a hosted web font, so I decided to build and append the two required <script> tags dynamically in an already-linked JavaScript file.
The <script> blocks are appending correctly in the head of the document, but function in the second block seems to be firing before the external script linked in the first <script> tag is fully loaded, and it's throwing an undefined error.
Here's the relevant piece of code:
document.getElementsByTagName("head")[0];
var tag = document.createElement('script');
tag.setAttribute("src", "http://use.typekit.com/izj3fep.js");
document.getElementsByTagName("head")[0].appendChild(tag);
try {
Typekit.load(); // This is executing too quickly!
} catch(e){
console.log("Hosted fonts failed to load: " + e);
}
I tried moving the try block to the window.onload event, but that fires before any of this code is called.
I guess I could dynamically load jQuery and then use it's ready event, but that seems pretty heavy-handed. I'm hesitant to pull in a library on this project, as the client has a lot of custom JavaScript that could potentially clash with it.
What else can I try?
You need to hook into the script element's onload event and execute your code there:
document.getElementsByTagName("head")[0];
var tag = document.createElement('script');
tag.onload = onTagLoaded;
tag.setAttribute("src", "http://use.typekit.com/izj3fep.js");
document.getElementsByTagName("head")[0].appendChild(tag);
function onTagLoaded() {
try {
Typekit.load(); // This is executing too quickly!
} catch(e){
console.log("Hosted fonts failed to load: " + e);
}
}
You can load it with yepnope ( http://yepnopejs.com/ ). I know it's a library, but it's very light (free if your client is already using modernizr). It's well worth it. Hopefully the client doesn't have another yepnope function, and you don't have to worry about the clash.
Are you using jQuery? If not, I highly recommend it. It'll make your life so much easier:
$.getScript('http://use.typekit.com/izj3fep.js', function(data, textStatus){
try {
Typekit.load(); //executes properly now!
} catch(e) {
console.log("Hosted fonts failed to load: " + e);
}
});
Combining the scripts into one big seems to be the easiest solution.
Could someone please explain the behaviour of jQuery's getScript() function?
Consider a javascript file test.js:
var tmp = 'a variable';
alert('here');
When test.js is loaded via html's <script> tag, everything works fine: tmp variable is available in the global scope and a message box appears.
I'm trying to get the similar behavior via this code:
<script>
$(document).ready(function() {
$.getScript("static/js/proto/test.js");
setTimeout(function() {
// at this point tmp should be available
// in the global scope
alert(tmp);
} , 2000); // 2 seconds timeout
}
</script>
But browser's error console reports an "Undefined variable tmp" error.
What am I doing wrong?
Thank you.
$.getScript may be asynchronous, use the callback parameter:
$.getScript("static/js/proto/test.js", function() {
// here you are sure that the script has been executed
});
See the documentation for $.getScript: http://api.jquery.com/jQuery.getScript
The real problem with the script was my lack of experience with JS in general and particulary in AJAX: I was trying to run this script on a local machine without a web server.
Guess what: AJAX expects status '200' from a web server to load a document asynchronously. As there was no web server, the status of the async call was '0'.
Thank you everyone for answering.
My web app dynamically loads sections of its UI with jquery.ajax. The new UI sections come with script though. I'm loading them as such:
Use...
$.ajax({
url: url,
dataType: 'html',
success: function(data, textStatus, XMLHttpRequest) {
$(target_selector).html( data );
update_ui_after_load();
}
});
This almost works. The problem is that the scripts included in the dynamic part of the page run before the new page fragment is inserted into the DOM. But often these scripts want to modify the HTML they're being delivered with. My best hacky solution so far is just to delay the scripts some reasonable amount of time to let the DOM insertion happen, by wrapping them in a setTimeout:
window.setTimeout( function() {
// process downloaded Fragment
}, 300);
Obviously this is unreliable and hideous. What's a better way?
Using
$(function);
will make the function you pass to jQuery to be run after the fragment is inline on the page.
I found it in
ASP.NET Ajax partial postback and jQuery problem
after looking at your question.
Are you familiar with the live() function? Might be what you're looking for here.
http://api.jquery.com/live/
The problem is that the scripts included in the dynamic part of the page run before the new page fragment is inserted into the DOM. But often these scripts want to modify the HTML they're being delivered with.
I'm fairly sure that in that case, the only sensible thing is to place the script after the HTML element.
Everything else would become kludgy quickly - I guess you could implement your own "ready" handler that gets executed after your HTML has been inserted, but that would be a lot of work to implement for no real gain.
I solved it by making a new simple ready handler system as follows...
var ajaxOnLoad = (function() {
var ajaxOnLoad = {};
var onLoadQueue=[];
ajaxOnLoad.onLoad= function(fn) {
onLoadQueue.push(fn);
}
ajaxOnLoad.fireOnLoad = function() {
while( onLoadQueue.length > 0 ) {
var fn = onLoadQueue.shift();
fn();
}
}
window.ajaxOnLoad = ajaxOnLoad;
return ajaxOnLoad;
})();
So in the pages which get .ajax() loaded, the scripts are queued to run with
ajaxOnLoad.onLoad( function() {
// Stuff to do after the page fragment is inserted in the main DOM
});
and in the code which does the insertion, before the update_ui_after_load() call, run
ajaxOnLoad.fireOnLoad();
A more complete solution could parse the pages, find script tags, and queue them up automatically. But since I have complete control of the fragments being inserted, it's easier for me to switch to using ajaxOnLoad.onLoad.