How to force a script reload and re-execute? - javascript

I have a page that is loading a script from a third party (news feed). The src url for the script is assigned dynamically on load up (per third party code).
<div id="div1287">
<!-- dynamically-generated elements will go here. -->
</div>
<script id="script0348710783" type="javascript/text">
</script>
<script type="javascript/text">
document.getElementById('script0348710783').src='http://oneBigHairyURL';
</script>
The script loaded from http://oneBigHairyURL then creates and loads elements with the various stuff from the news feed, with pretty formatting, etc. into div1287 (the Id "div1287" is passed in http://oneBigHairyURL so the script knows where to load the content).
The only problem is, it only loads it once. I'd like it to reload (and thus display new content) every n seconds.
So, I thought I'd try this:
<div id="div1287">
<!-- dynamically-generated elements will go here. -->
</div>
<script id="script0348710783" type="javascript/text">
</script>
<script type="javascript/text">
loadItUp=function() {
alert('loading...');
var divElement = document.getElementById('div1287');
var scrElement = document.getElementById('script0348710783');
divElement.innerHTML='';
scrElement.innerHTML='';
scrElement.src='';
scrElement.src='http://oneBigHairyURL';
setTimeout(loadItUp, 10000);
};
loadItUp();
</script>
I get the alert, the div clears, but no dynamically-generated HTML is reloaded to it.
Any idea what I'm doing wrong?

How about adding a new script tag to <head> with the script to (re)load? Something like below:
<script>
function load_js()
{
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.src= 'source_file.js';
head.appendChild(script);
}
load_js();
</script>
The main point is inserting a new script tag -- you can remove the old one without consequence. You may need to add a timestamp to the query string if you have caching issues.

Here's a method which is similar to Kelly's but will remove any pre-existing script with the same source, and uses jQuery.
<script>
function reload_js(src) {
$('script[src="' + src + '"]').remove();
$('<script>').attr('src', src).appendTo('head');
}
reload_js('source_file.js');
</script>
Note that the 'type' attribute is no longer needed for scripts as of HTML5. (http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#the-script-element)

Creating a new script tag and copying the contents of the existing script tag, and then adding it, works well.
var scriptTag = document.createElement('script');
scriptTag.innerText = "document.body.innerHTML += 'Here again ---<BR>';";
var head = document.getElementsByTagName('head')[0];
head.appendChild(scriptTag);
setInterval(function() {
head.removeChild(scriptTag);
var newScriptTag = document.createElement('script');
newScriptTag.innerText = scriptTag.innerText;
head.appendChild(newScriptTag);
scriptTag = newScriptTag;
}, 1000);
This won't work if you expect the script to change every time, which I believe is your case. You should follow Kelly's suggestion, just remove the old script tag (just to keep the DOM slim, it won't affect the outcome) and reinsert a new script tag with the same src, plus a cachebuster.

Small tweak to Luke's answer,
function reloadJs(src) {
src = $('script[src$="' + src + '"]').attr("src");
$('script[src$="' + src + '"]').remove();
$('<script/>').attr('src', src).appendTo('head');
}
and call it like,
reloadJs("myFile.js");
This will not have any path related issues.

Use this function to find all script elements containing some word and refresh them.
function forceReloadJS(srcUrlContains) {
$.each($('script:empty[src*="' + srcUrlContains + '"]'), function(index, el) {
var oldSrc = $(el).attr('src');
var t = +new Date();
var newSrc = oldSrc + '?' + t;
console.log(oldSrc, ' to ', newSrc);
$(el).remove();
$('<script/>').attr('src', newSrc).appendTo('head');
});
}
forceReloadJS('/libs/');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

I know that is to late, but I want to share my answer.
What I did it's save de script's tags in a HTML file,
locking up the scripts on my Index file in a div with an id, something like this.
<div id="ScriptsReload"><script src="js/script.js"></script></div>
and when I wanted to refresh I just used.
$("#ScriptsReload").load("html_with_scripts_tags.html", "", function(
response,
status,
request
) {
});

Related

Displaying Page Load Time On Webpage

I want to display the loading time of a webpage on site. I can get this working by writing to console.log but writing the information to a page is beyond me.
In my head I have
<!-- Loading Time -->
<script type="text/javascript">
var loadTime = window.performance.timing.domContentLoadedEventEnd- window.performance.timing.navigationStart;
</script>
Then I have this to write to the console log
<script type="text/javascript">
window.onload = function () {
var loadTime = window.performance.timing.domContentLoadedEventEnd-window.performance.timing.navigationStart;
console.log('Page load time is '+ loadTime / 1000);
}
</script>
This works perfectly but I really want to display the loading time on a webpage. How do I achieve this? My page is a simple html / css site.
Three possible methods are:
Just writing to the document directly (should not be used because of the reasons described here):
document.write(loadTime);
Adding an HTML element and setting its inner text to loadTime:
function displayLoadtime(loadtime){
document.getElementById("loading-time").innerText = loadtime;
}
<p id='loading-time'>Loading...</p>
Creating the element in Javascript and displaying the loadTime using it:
function displayLoadingtime(loadtime){
let p = document.createElement("p");
p.innerText = loadtime;
document.getElementById("loading-time-container").appendChild(p);
}
<div id='loading-time-container'></div>
I know what I answered is some beginners' stuff and you probably know it, but I will edit the answer in case you give more details, because I don't see any problems in displaying it if you already have the loadTime.
You can write the time you calculated into an element of the webpage using the innerText property of a Node.
window.onload = function() {
var loadTime = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart;
console.log('Page load time is ' + loadTime / 1000);
performanceDisplay = document.getElementById("performance-display") // get a reference to the paragraph
performanceDisplay.innerText = loadTime / 1000 // put the value of the variable loadTime into the paragraph
}
<body>
<p id="performance-display"></p>
</body>
Or, if you do not want to put the paragraph manually into the HTML, you can create it in the JavaScript using document.createElement:
window.onload = function() {
var loadTime = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart;
console.log('Page load time is ' + loadTime / 1000);
performanceDisplay = document.createElement("p") // create a new paragraph element
performanceDisplay.innerText = loadTime / 1000 // put the value of the variable loadTime into the paragraph
document.body.appendChild(performanceDisplay) // add the paragraph element to the body of the document
}
Welcome to StackOverflow, Rylad!
You can easily put it into your webpage by referencing an HTML element.
Ie. add an element with the id timeContainer to your page and set its innerHTML to your variable, loadTime. Here's an example:
<body>
<span id="timeContainer">
The load time will be displayed here when the page is finished loading
</span>
<script type="text/javascript">
window.onload = function() {
var loadTime = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart;
console.log(loadTime)
document.getElementById("timeContainer").innerText = loadTime;
}
</script>
</body>
Try this,
Simple way to get loading time
<body>
<span id="loadingTime"></span>
<script>
window.addEventListener('load', (e) => {
let timestemp = new Date(e.timeStamp).getTime()
console.log('loading time is', timestemp)
document.getElementById('loadingTime').innerText = "loading time is "+timestemp
})
</script>
</body>

Run JavaScript inside <script src="..."></script> Tags?

I've a JavaScript file that processes tab switches. Here is the source:
var tCount = 0;
function SwitchToTab(id) {
if (id < 0 || id > tCount) { id = 0; }
for (var i = 0; i < tCount; i++) { document.getElementById("tab" + i).className = ""; }
document.getElementById("tab" + id).className = "active";
for (var i = 0; i < tCount; i++) { document.getElementById("area" + i).style.display = "none"; }
document.getElementById("area" + id).style.display = "";
}
function InitializeTabs(initialTabId, tabsCount) {
tCount = tabsCount;
SwitchToTab(initialTabId);
}
I'm trying to make it as short as possible like this:
<script src="Resources/Tabs.js">InitializeTabs(0, 4);</script>
It doesn't works but it works if I separate them like this:
<script src="Resources/Tabs.js"></script>
<script>InitializeTabs(0, 4);</script>
So, is there any way to run JavaScript inside <script src="..."></script> tags? What I am missing?
No, this is not possible. The html spec dictates that a <script> tag does one or the other.
<script>Tag Html Spec, emphasis mine.
The script may be defined within the contents of the SCRIPT element or in an external file. If the src attribute is not set, user agents must interpret the contents of the element as the script. If the src has a URI value, user agents must ignore the element's contents and retrieve the script via the URI.
You are suppose to do it the second way. in <script src="Resources/Tabs.js">InitializeTabs(0, 4);</script> you are referencing an external javascript file, your inline code should go into a second script block.
You can either use src, or put JavaScript inside the tag.
But not both at once. There's no downside to using two tags anyway (apart from larger file size).
When you include <script src="Resources/Tabs.js"></script>, you are mentioning that you want to use the Javascript which is included inside the Tabs.js file so that the compiler knows where to look for InitializeTabs function, when it is trying to execute the function.
Now if you want to include some Javascript inline, that is inside the HTML, hen you use the <script>... JAVASCRIPT HERE .... </script>
You need to do it like this
<script src="Resources/Tabs.js"></script>
<script>InitializeTabs(0, 4);</script>
You can't put javascript inside of <script src="... tags, but you could run a JavaScript file which parses the HTML, looking for <script src tags, which converts it into two tags.
For example,
<script src="Resources/Tabs.js">InitializeTabs(0, 4);</script>
would have to be converted into
<script src="Resources/Tabs.js"></script>
<script>InitializeTabs(0, 4);</script>
Here's the code I tried:
var tags = document.querySelectorAll("script[src]");
[].forEach.call(tags, function(elem){
var text = elem.innerText;
var src = elem.src;
var parent = elem.parentNode;
parent.removeChild(elem);
var newTag = document.createElement('script');
newTag.setAttribute('src', src);
parent.appendChild(newTag);
var newTag = document.createElement('script');
var t = document.createTextNode(text);
newTag.appendChild(t);
parent.appendChild(newTag);
});
in a JSFiddle

Javascript add new class in body tag

If OS is MAC I set a variable & then on condition I want to add new class in body tag.
Here is my code
<script type="text/javascript" language="javascript">
var mac=0;
if(navigator.userAgent.indexOf('Mac') > 0){
mac=1;
}else{
mac=0;
}
if(1==mac){
//document.body.className+='mac-os';
//document.getElementsByTagName('body')[0].className+='mac-os';
$('body').addClass('mac-os');
}else{
//document.body.className+='win-os';
//document.getElementsByTagName('body').className+='win-os';
//$('body').addClass('mac-os');
//$("body.className").addClass('win-os');
//document.body.className += " " + 'win-os';
$("body").addClass('win-os');
}
</script>
I have tried all but fail.
It's likely that the body element simply doesn't exist at the point your current code is being executed.
Ensure that your code is not executed until the DOM is ready, by putting it inside a ready handler:
$(document).ready(function() {
// your code
...
});
It would also work if you put it inside the <body> element, typically at the end of the page.
If your script is in head your should wait until the body to be loaded, Change your code to:
$(document).ready(function(){
var mac=0;
if(navigator.userAgent.indexOf('Mac') > 0){
mac=1;
}else{
mac=0;
}
if(1==mac){
//document.body.className+='mac-os';
//document.getElementsByTagName('body')[0].className+='mac-os';
$('body').addClass('mac-os');
}else{
//document.body.className+='win-os';
//document.getElementsByTagName('body').className+='win-os';
//$('body').addClass('mac-os');
//$("body.className").addClass('win-os');
//document.body.className += " " + 'win-os';
$("body").addClass('win-os');
}
});
Or put your script into body tag:
<body>
<!-- your script -->
<!-- others -->
</body>
The html elements don't exist until after the page loads, but your js is executing before the <body> tag is even read by the browser. Your script tags come before the <body> tag, so the browser executes the js code first. If you need to delay execution of your js code until after the page loads(as is the case with most js code)--and you don't want to use jquery--then you can do this:
<script type="text/javascript">
window.onload = function() {
//js code here
}
</script>
That function will not execute until the onload event occurs, which is after the page loads. The problem with the onload event is that all the images must load completely before the event fires, and that can take a long time, which will delay rendering any styles set by the js, or allowing buttons to fire onclick handlers set by the js.
As an alternative, you can put your script tags just before the closing body tag:
...
<script type="text/javascript">
//js code here
</script>
</body>
In that case, all the html on the page will have been parsed by the browser when the javascript tags are encountered, and as a result all the html elements will exist. <img> tags that are parsed will exist, but the browser doesn't wait for them to load--the browser continues on and parses the rest of the html while the images are loading. Even the body element exists even though its closing tag hasn't been seen yet.
Better still is to link to a js file, so that your js code isn't cluttering up the html:
<script type="text/javascript" src="myjs.js"></script>
</body>
Also, if you have this:
<body class="bgcolor">
...and your js code does this:
document.getElementsByTagName('body')[0].className += 'mac-os';
...then you will get his:
<body class="bgcolormac-os">
...which is not what you want. You need to add a space in there:
.... += ' mac-os';
...so that you get:
<body class="bgcolor mac-os">
A comment on your code style: you need to add more spaces, for instance:
if (1 == mac) {
document.getElementsByTagName('body')[0].className += 'mac-os';
}
else {
document.getElementsByTagName('body')[0].className += 'win-os';
}
Also, don't use 'cuddled' else clauses--they are really ugly. Consider using the style in the example where the else starts on a new line. Code clarity is what you are aiming for--not the fewest number of bytes. You might also consider indenting just 2 spaces--js statements can get pretty long, so conserving space there can be helpful.
And to avoid having to re-type those long document.get.... statements and make your code easier to read, you can do thing things like this:
var mybody = document.getElementsByTagName('body')[0];
if (1 == mac) {
mybody.className += ' mac-os';
}
else {
mybody.className += ' win-os';
}
Your code works, maybe you forgot to wrap your code with
$(function () {
//your code
});
?
$(function () {
var mac = 0;
if (navigator.userAgent.indexOf('Mac') > 0) {
mac = 1;
} else {
mac = 0;
}
if (1 == mac) {
//document.body.className+='mac-os';
//document.getElementsByTagName('body')[0].className+='mac-os';
$('body').addClass('mac-os');
} else {
//document.body.className+='win-os';
//document.getElementsByTagName('body').className+='win-os';
//$('body').addClass('mac-os');
//$("body.className").addClass('win-os');
//document.body.className += " " + 'win-os';
$("body").addClass('win-os');
}
});
Just put your jquery codes in $(document).ready(...) block to be sured that they execute in correct time...:
$(document).ready(function() {
// jquery codes...
$(document.body).addClass('your-class');
// ...
});

Changing innerHTML of script tags in IE for loading google plusone button explicitly

To add Google's plusone button on your website the following script tag is to be inserted (for explicit load).
<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
{"parsetags": "explicit"}
</script>
It looks pretty straight forward in HTML. However I wan't to insert the script using a JS file. So I use the following code:
var e = document.createElement('script');
e.src = "https://apis.google.com/js/plusone.js";
e.id = "googplusonescript";
e.innerHTML = '{"parsetags": "explicit"}';
document.getElementsByTagName("head")[0].appendChild(e);
It works pretty awesome in all the browsers except IE because IE doesn't allow us to write the innerHTML of script tags. Anywork arounds anyone ? (I have jquery inserted in the page. So can use jquery too.)
Came across the same issue.
Under IE you should use
script.text = '{"parsetags": "explicit"}';
instead of script.innerHTML
try creating a textNode and appending it to your script tags:
var myText = document.createTextNode('{"parsetags": "explicit"}');
myScriptTag.appendChild(myText);
Try the following:
window['___gcfg'] = { parsetags: 'explicit' };
var ispoloaded;
function showpo() {
var pohd = document.getElementsByTagName('head')[0];
var poscr = document.createElement('script');
poscr.type ='text/javascript';
poscr.async = true;
poscr.text ='{"parsetags": "explicit"}'; //works on IE too
poscr.src = "http://apis.google.com/js/plusone.js";
pohd.appendChild(poscr);
ispoloaded = setInterval(function () {
//check if plusone.js is loaded
if(typeof gapi == 'object') {
//break the checking interval if loaded
clearInterval(ispoloaded);
//render the button, if passed id does not exists it renders all plus one buttons on page
gapi.plusone.go("idthatexists");
}
}, 100); //checks every 0.1 second
}

How to load all scripts, stylesheets, and markup from one js file?

The following small snippet of code cannot be changed once deployed (it's in an RIA) so everything must be loaded via a bootstrapper.js file:
<div id="someDivID"></div>
<script type="text/javascript" src="bootstrapper.js"></script>
What's the best way to load up all the js, css, and markup? Is there a better (cleaner, faster, crisper) way than the following?:
function createDivs() {
var jsDiv = document.createElement('div');
jsDiv.id = 'allJavascriptHere';
var contentDiv = document.createElement('div');
contentDiv.id = 'allContentHere';
document.getElementById("someDivID").appendChild(jsDiv);
document.getElementById("someDivID").appendChild(contentDiv);
function importScript(url){
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
document.getElementById("jsDiv").appendChild(script);
}
importScript("http://example.com/jquery-1.4.2.min.js");
importScript("http://example.com/anotherScript.js");
}
window.onload = function(){
$.get("http://example.com/someHTML.html", function(data) {
$('#contentDiv').html(data);
setTimeout("javaScript.init()", 200);
});
}
with stylesheets in the someHTML.html file as so:
<style type="text/css">
#import url("example.com/styleSheet.css");
</style>
(note: I don't know why I need the setTimeout but for some reason I do. Maybe your answer won't require it.)
You can use jQuery's $.getScript() to import scripts.
I recently wrote a function to import CSS.
var getCss = function(file, callback) {
if (typeof callback !== 'function') {
throw 'Not a valid callback';
};
$.get(file, function(css) {
var top = $('head > link[rel=stylesheet]').length ? $('head > link[rel=stylesheet]:last') : $('head > *:last');
top.after('<link rel="stylesheet" type="text/css" href="' + file + '">');
callback();
});
};
If your css is also in that js file, you can simply add css code to the documents style tag. It can be useful in some situations, where using different css file is not allowed etc.
If you're looking to load CSS asynchronously in an easy fashion similar to $.getScript check out loadCSS, a standalone library for loading CSS without a dependency on jQuery.

Categories

Resources