Script tag injection with synchronous execution - javascript

I have to add a script tag via some JavaScript and have it execute in full as the later statements rely on it.
<html>
<head>
<title>Injecting Script Tags</title>
</head>
<body>
<h1>Injecting Script Tags</h1>
<script>
console.log('starting');
var newScriptTag = document.createElement('script');
newScriptTag.src = 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js';
newScriptTag.type = 'text/javascript';
document.head.appendChild(newScriptTag);
try {
var now = moment().format('HH:mm');
console.log(`moment loaded. The time is ${now}`);
} catch (e) {
console.log(`Moment not loaded: ${e}`);
}
</script>
</body>
</html>
As the snippet above shows, the moment() isn't available on the statement after the tag insertion.
I think it could be done with eval(...), but that option isn't popular.

use onload event
<html>
<head>
<title>Injecting Script Tags</title>
</head>
<body>
<h1>Injecting Script Tags</h1>
<script>
console.log('starting');
var newScriptTag = document.createElement('script');
newScriptTag.src = 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js';
newScriptTag.type = 'text/javascript';
newScriptTag.onload = function(){
try {
var now = moment().format('HH:mm');
console.log(`moment loaded. The time is ${now}`);
} catch (e) {
console.log(`Moment not loaded: ${e}`);
}
};
document.head.appendChild(newScriptTag);
</script>
</body>
</html>

Related

How to append Google Analytics code in head using JS

I am trying to append Google Analytics Script code within head when the UserAgent is not bot(googlebot).
What I am trying:
<script type="text/javascript">
var agent = navigator.userAgent.toLowerCase();
var CheckUA = agent.match(/Googlebot/i);
if(!CheckUA) {
var scriptTagAnalytics = "***MY GA script CODE***";
document.head.prepend(scriptTagAnalytics);
}
</script>
My Google Analytics Code is:
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-123456789-1">
</script>
<script>
function gtag(){
dataLayer.push(arguments)
}
window.dataLayer=window.dataLayer||[],
gtag("js",new Date),
gtag("config","UA-123456789-1");
</script>
I tested it and it is reflecting in Google Analytics. The only thing is the source code will be visible.
if(!CheckUA) {
(function() {
const head = document.getElementsByTagName("head")[0];
var myScript = document.createElement('script');
myScript.setAttribute('src', 'https://www.googletagmanager.com/gtag/js?id=UA-123456789-1');
myScript.onload = function() {
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
console.log('window.dataLayer Executed', window.dataLayer)
gtag('config', 'UA-123456789-1');
}
head.insertBefore(myScript, head.children[1]);
})();

Call Function from Dynamically loaded Javascript file

I have a base.js file that called from my index.html file and this base.js call script script1.js or script2.js according to parameter passed to the base.js file and then I have another script called editor.js will call a function -with the same name but different implementation- from script1.js or script2.js, so my question is how I execute the function after loading the script1.js or script2.js
Samples of what I mean:
index.html
<html>
<head>
<meta charset="utf-8">
<title>Rich Text Editor</title>
<link rel="stylesheet" type="text/css" href="content/css/app-min.css">
</head>
<body>
<div class="new-question page">
<p>
<textarea id="textBox1" class="html-editor" cols="70" rows="10">
</textarea>
</p>
<p>
<button id="submit">Submit</button>
</p>
</div>
<script type="text/javascript" src="base.js"></script>
<script>
LoadFunction("multiply");
</script>
<script type="text/javascript" src="editor.js"></script>
<script type="text/javascript" src="content/js/script.js"></script>
<script type="text/javascript" src="content/js/custom-script.js"></script>
</body>
</html>
base.js
let LoadFunction = function (type) {
//loading localization script
let script = document.createElement('script');
script.type = 'text/javascript';
document.querySelector('body').appendChild(script );
if(type == "multiply")
script.src = `script1.js`
else
script.src = `script2.js`
}
script1.js
function Calculate(a,b){
return a*b;
}
script2.js
function Calculate(a,b){
return a+b;
}
editor.js
var result = Calculate(5,9);
console.log(result);
Consider reading more about Promises
https://developer.mozilla.org/he/docs/Web/JavaScript/Reference/Global_Objects/Promise
the following is an example using your code,
I don't think it fully do what you're looking for (as I called the loadFunction in the editor.js and not in the main file, but I believe this example + the documentation above will help you get the idea). Good luck :)
base.js
let loadFunction = function (type) {
//loading localization script
let script = document.createElement('script');
script.type = 'text/javascript';
document.querySelector('body').appendChild(script );
if(type == "multiply")
script.src = `script1.js`
else
script.src = `script2.js`
// return a promise
return new Promise((res, rej) => {
script.onload = function() {
res();
}
script.onerror = function () {
rej();
}
});
}
editor.js
loadFunction('multiple')
.then(() => {
// The script file has been loaded.
// We can use the function.
var result = Calculate(5,9);
console.log(result);
})
.catch(() => {
console.error('Could not load the script file.');
});
Haven't fully tested the code.

how to load main.js only after facebook response status is connected in cocos2d-js

I am using cocos2d-js for game development. In a script of index.html I want to load main.js only when some conditions will be fulfilled.
The sample code is the below
<script>
if(user_id == data.id)
{
// call the main.js
}
</script>
I tried the below
<script>
if(user_id == data.id)
{
(function(document){
var s = document.createElement('script');
s.id = "external_content";
s.async = true;
s.src = "main.js";
document.getElementsByTagName('body')[0].appendChild(s);
s.onload = function() {
document.write(external_content);
}
}(document));
}
</script>
But it does not work. I can not call the main.js from inside another sript. What can I do ? Please help.

window onload conflicts with body onload javascript

My client puts our below JS code in his website in the <head> and is complaining our tags are not firing. Below is the sample code from client:
<html>
<head>
<script type="text/javascript">
function create() {
try {
var baseURL = "https://serv2ssl.vizury.com/analyze/analyze.php?account_id=VIZVRM1125";
var analyze = document.createElement("iframe");
analyze.src = baseURL;
var node = document.getElementsByTagName("script")[0];
node.parentNode.insertBefore(analyze, node);
} catch (i) {
}
}
var existing = window.onload;
window.onload = function() {
if (existing) {
existing();
}
create();
}
</script>
</head>
<body onload="javascript:clientfunction();">
<script type="text/javascript">
function clientfunction()
{
//client code is replcad here
document.write("Hello testing");
}
</script>
</body>
</html>
On page Load clientfunction() is calling, our create() function is not firing.
Please can anybody help me why our tags are not firing and what is the alternative solution for this issue?
copy paste and check running following
<html>
<head>
<script type="text/javascript">
function create() {
alert("Gdfg");
try {
var baseURL = "https://serv2ssl.vizury.com/analyze/analyze.php?account_id=VIZVRM1125";
var analyze = document.createElement("iframe");
analyze.src = baseURL;
var node = document.getElementsByTagName("script")[0];
node.parentNode.insertBefore(analyze, node);
} catch (i) {
}
}
window.onload=create;
window.onload=clientfunction;
</script>
</head>
<body onload="clientfunction(); create()">
<script type="text/javascript">
function clientfunction()
{
alert("fdsfsdf");
//client code is replcad here
document.write("Hello testing");
}
</script>
</body>
</html>

Remove specific <script> tag in <head> tag by onclick event

<head>
<script type="text/javascript">
function include(filename, status){
if(status == 'on'){
var head = document.getElementsByTagName('head')[0];
script = document.createElement('script');
script.src = filename;
script.type = "text/javascript";
head.appendChild(script);
} else {
// The code that wipes the script tag above
}
}
</script>
</head>
<body>
<input type="button" value="OPEN" onclick="include('script.js', 'on')">
<input type="button" value="CLOSE" onclick="include('', 'off')">
</body>
I want to remove the specific tag in tag by onclick event.
What code should be written in the ELSE area, When I click the "CLOSE" botton?
The easiest way, would be to somehow maintain a link to the created element. For example, you could put the include function into a closure and have a private variable, to hold the reference:
var include = (function(){
// the reference to the script
var theScript;
return function (filename, status){
if(status == 'on'){
// adding a script tag
var head = document.getElementsByTagName('head')[0];
theScript= document.createElement('script');
theScript.src = filename;
theScript.type = "text/javascript";
head.appendChild( theScript )
}else{
// removing it again
theScript.parentNode.removeChild( theScript );
}
}
})();
One important note: By removing the <script> tag, you do not remove any of its objects, functions etc. from the DOM. So any action started within that <script> tag will prevail, even if you delete the element, that started it in the first place!
You could also add an ID to the ScriptElement
this will work for you
function include(filename, status){
if(status == "on"){
var head = document.getElementsByTagName('head')[0];
script = document.createElement('script');
script.src = filename;
script.type = "text/javascript";
script.id = "testScriptName";
head.appendChild(script);
}else{
(elem=document.getElementById("testScriptName")).parentNode.removeChild(elem)
}
}
Try using this:
function include(filename, status){
var head = document.getElementsByTagName('head')[0];
if(status == on){
script = document.createElement('script');
script.src = filename;
script.type = text/javascript;
head.appendChild(script)
}
else if(status == 'off'){
var scripts = head.getElementsByTagName('script');
if(scripts.length > 0){
head.removeChild(scripts[0]);
}
}
}

Categories

Resources