How to add dynamic timestamps for JS includes in static HTMLfile - javascript

So I have an interesting problem. I have a static site with some HTML files having javascript includes. Is there a way I can add a dynamic timestamp to these JS files in order to override caching and to have the latest version fetched.
Like:
<script async src="://main.lib.js?ts=1606903654"></script>
Earlier I could do this since the HTML was being generated dynamically using PHP. This is no longer the case and I am wondering how I can do this.
Any suggestions would be great!

Create your script element with JS and append it to HEAD.
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "://main.lib.js?ts=" + new Date().getTime();
script.async = "async";
head.appendChild(script);

Extending #alexP 's answer to enable the timestamp to remain constant for at max an hour.
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "://main.lib.js?ts=" + Math.floor((new Date()).setMinutes(0) / 100000);
script.async = "async";
head.appendChild(script);
However, I'm not certain if caching will work because it depends on the headers you send with the js file. In simple terms, if the caching works then you don't need this timestamp

Related

Javascript: best way to wait for script loaded synchonously before executing function?

I have the following problem:
I load a page inside a modal dialog. This page uses jQuery as dependency. Since I already use jQuery on the main page, for me, it is always available. Now we have the usecase, that also different pages (hosted on different domains) need to load that page if necessary.
So, I check if the jQuery variable exists on this page and if yes, just go on with my code.
If it does not exist, on top of the template, I dynamically create a script element like this:
<script>
if(!window.jQuery)
{
var script = document.createElement('script');
script.type = "text/javascript";
script.src = "path/to/jQuery";
document.getElementsByTagName('head')[0].appendChild(script);
}
</script>
And at the end of the template, I use a IIFE (to scope the jquery variable)
(function ($) {
.... code ....
})(jQuery);
However, since with this method, the script gets loaded asynchronously, sometimes I get the error: jQuery is undefined.
Now I came up by loading it synchronously, like this:
var xhrObj = new XMLHttpRequest();
// open and send a synchronous request
xhrObj.open('GET', "jquery.min.js", false);
xhrObj.send('');
// add the returned content to a newly created script tag
var se = document.createElement('script');
se.type = "text/javascript";
se.text = xhrObj.responseText;
document.getElementById('placeholder').appendChild(se);
This works fine, but the warning "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. to the end user's experience." made me think.
However, now I changed my code and just said
if (!window.jQuery) {
document.write('<scr' + 'ipt src="jquery.js"' + '>' + '</scr' + 'ipt>');
}
on top of my Template.
Dear javascript gurus, is this a reliable solution?
Use the onload attribute in async javascript
<script async src="siteScript.js" onload="window.MyInitialisation()"></script>
In javascript it would look like this:
<script>
if(!window.jQuery)
{
var script = document.createElement('script');
script.type = "text/javascript";
script.async = "async";
script.defer = "defer";
script.onload = function() {window.MyInitialisation()}
script.src = "path/to/jQuery";
document.getElementsByTagName('head')[0].appendChild(script);
}
</script>

load multiple javascript file with using one javascript file

i want to load multiple javascript file using one javascript file
i have four javascript
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script type="text/javascript" src="http://ec2-174-129-44-226.compute-1.amazonaws.com/apiTools/jquery.livequery.js"></script>
<script src="http://localhost/effbugs/apiTools/tools.js?apikey=fztxljpnxqtssgtiquwr&pid=1"></script>
i want to intergrate above four javascript in one javascript file that i will load one instead of four and i will work proper
please give me suggestion for that
please help me
thanks...
Well, there are a few options:
1. Combine them into one file
Here is how you can do it with cat:
cat jsfile1.js jsfile2.js jsfile3.js ... > combined.js
2. Load them via require.js
More info at requirejs.org.
3. Create an script element for each URL and append it to DOM
/**
* loader.js
*/
window.addEventListener('load', function () {
var head = document.getElementsByTagName('head')[0],
urls = ["http://code.jquery.com/jquery-1.10.1.min.js",
"http://code.jquery.com/jquery-migrate-1.2.1.min.js",
"http://ec2-174-129-44-226.compute-1.amazonaws.com/apiTools/jquery.livequery.js",
"http://localhost/effbugs/apiTools/tools.js?apikey=fztxljpnxqtssgtiquwr&pid=1"];
urls.forEach(function (url) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
head.appendChild(script);
});
});
You can do in this way to include all js files, But while loading I guess they loads asynchronously and they might not maintain order the order.
var scriptElement = document.createElement('script');
scriptElement.src = 'http://code.jquery.com/jquery-1.10.1.min.js';
document.getElementsByTagName("head")[0].appendChild(scriptElement);
Its quite simple, you just copy the content of all 4 files and place them into 1 file in order like this.
Master.js:
// Content of jquery-1.10.1.min.js
// Content of jquery-migrate-1.2.1.min.js
// Content of jquery.livequery.js
// Content of tools.js
Or
Master.js:
var script = document.createElement('script');
script.src = 'jquery-1.10.1.min.js';
document.head.appendChild(script);
// Do this for each file

Can I Load CSS Using the "load.js" Library?

I recently found out about load.js, but I can't seem to find any indication of whether or not this is possible... (Note: I can't find a 'load.js' tag..)
I've got load.js successfully loading all my JS files, so I know it works. Has anyone got it working for loading CSS files as well?
Update: remyabel's solution worked perfectly for loading the physical files, but it seems there are a few quirks to this process...
For some reason, the order in which the CSS files are loaded and whether they're all done in one load(file1,file2); or in stages with load(file1).then(file2); seems to affect how the style rules are applied to the markup. I'm going to set up a few test cases on my local machine to try work out how or why this happens, but for now at least the files are being loaded.
Final Note:
Following on from the solution posted below, I've decided to use head.appendChild(script); instead of head.insertBefore(script, head.firstChild); to add the CSS elements to the DOM (still uses the original method for JS files).
This doesn't affect the order in which files are fetched and processed, but it makes Load.js insert my CSS links in the same order they were listed and at the end of the header instead of the beginning.
Direct from the source code
function asyncLoadScript(src) {
return function (onload, onerror) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
My suggestion is to modify the script (which doesn't seem to contain much) to mirror the function but for a link tag, rather than a script tag.
to reflect OP's comment
The script is built on top of chain.js so it may be more complicated than expected.
Unless you want something else, I'm pretty sure what I wrote above is what you need to change, so it would look like:
function asyncLoadScript(src) {
return function (onload, onerror) {
// Get file extension
var ext = src.split('.').pop();
if (ext == "js")
{
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
} else if (ext == "css")
{
var script = document.createElement('link');
script.type = 'text/css';
script.href = src;
script.rel = "stylesheet";
}
Theoretically that should work. Make another comment if it doesn't work.

Modify "src=" in <script> tags before loading--without jQuery

Basically, I want to do this:
<script src=" path + '/jquery.js'"></script>
(Obviously that won't work.)
I have a standalone page loading external scripts with <script>, but the URL needs to be prefixed with the variable path (because the page is run on different servers in different environments). I easily get path from the URL which always ends with "?path=X" where X is the actual path.
If I had jQuery, I know I could use getScript() to dynamically load external .js files, but jQuery is one of the files I need to load! I don't need anything too complicated here, no need to worry about encoding or file-types, it's a fairly simple situation except for the changing servers.
You need to use plain javascript if jquery not loaded. Something like that:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", path + '/jquery.js');
document.getElementsByTagName("head")[0].appendChild(fileref);
fileref.onload = function(){alert('loaded')};
You can load JS files by inserting them into the head with javascript, and at the same you can use your variable for the path when setting the source attribute:
<script type="text/javascript">
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = path + '/jquery.js';
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
</script>

Generate script block containing custom language at runtime

I'm including a funky script (from the german social network VZ) in my page which requires me to insert a script block containing a custom "language":
<script type="vz/login">
client_id : c47a1d7f134b88c9f12448e08f2ef7289e9fc8
redirect_uri : http://game.example.com/vzcallback.html
callback : logResponse
fields : emails,gender,birthday
</script>
Can I insert such a block into my page at runtime using Javascript (no PHP or other server-side code)? I need this to set client_id dynamically.
Additionally I also need to insert something like:
<script src="https://secure.studivz.net/Js/id/v4/library.js"
data-authority="platform-redirect.vz-modules.net/r"
data-authorityssl="platform-redirect.vz-modules.net/r" type="text/javascript">
</script>
But I don't think adding those data-attributes will be a hard challenge.
Yes you can,
var el = document.createElement("script");
el.setAttribute("type","vz/login");
el.innerHTML = "client_id : "+new_client_id
+"\nredirect_uri : http://game.example.com/vzcallback.html"
+"\ncallback : logResponse"
+"\nfields : emails,gender,birthday";
document.body.appendChild(el);
For the second snipped use
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = 'https://secure.studivz.net/Js/id/v4/library.js';
newScript.setAttribute("data-authority","platform-redirect.vz-modules.net/r");
newScript.setAttribute("data-authorityssl", "platform-redirect.vz-modules.net/r");
headID.appendChild(newScript);
You can add the vz/login script node to the dom at runtime. But you need to ensure that the vz/login node has been added before the JS that is looking for it.

Categories