This question already has answers here:
Dynamically add script tag with src that may include document.write
(16 answers)
Closed 3 years ago.
We have this script which we want to run only if user agent is ReactSnap. I tried doing this but it does not seem to be working.
<script>
if(navigator.userAgent!=='ReactSnap'){
<script src='//cdnt.netcoresmartech.com/smartechclient.js'</script>
}
</script>
The operator you are using in your conditional statement - !== is checking to see if the condition is not true.
The correct syntax is if(navigator.userAgent=="ReactSnap")
You are also trying to write html in a javascript context.
You should create your script tag using javascript, like the below example:
if(navigator.userAgent=="ReactSnap"){ // check userAgent
var script = document.createElement("script"); // create a script tag
script.setAttribute("type","text/javascript"); // set type to js
script.setAttribute("src", "//cdnt.netcoresmartech.com/smartechclient.js") // define src for script tag
document.head.appendChild(script); // load script into document head, or change this to a specific location
}
This solution waits to add the script element to the page until we know the condition is true (tested in Chrome):
<body>
<div>Page content goes here</div>
<script>
let conditionalScript = document.createElement("script");
conditionalScript.innerHTML = "alert('woo!')";
// (But set .src instead of .innerHTML)
let userAgent = 'ReactSnap';
if(userAgent == 'ReactSnap'){
// (But check `navigator.userAgent` instead of `userAgent`)
document.querySelector("body").appendChild(conditionalScript);
}
</script>
</body>
I'd suggest using createElement, changing the source with setAttribute and appending it to the head like this.
if(navigator.userAgent!=='ReactSnap'){
let smartTech = document.createElement('script');
smartTech.setAttribute('src', '//cdnt.netcoresmartech.com/smartechclient.js');
document.head.appendChild(smartTech);
}
You can try something like this:
<script>
if(navigator.userAgent=='ReactSnap'){
var script = document.createElement('script');
script.src = "//cdnt.netcoresmartech.com/smartechclient.js";
document.head.appendChild(script);
}
</script>
Related
This question already has answers here:
How to append <script></script> in JavaScript? [duplicate]
(6 answers)
Closed 4 years ago.
So i have this script tag
<script async="async" data-cfasync="false" src=""></script>
That I'd like to be able to insert dynamically. I've tried setting it to a variable,
let scriptTag = '<script async="async" data-cfasync="false" src=""></script>';
and adding it using innerHTML to my content div but that doesn't seem to work. I know I'm going about this very wrong and part of me thinks this probably isn't even possible.
The reason I want to do this is so that I can turn ads on and off for testing purposes so my views during testing don't affect the analytics, is this something I should even be worrying about or is it negligible. I just know that I've been banned from chartboost for exactly this without having a testing variable that turned ads on and off.
Edit: Yes this is similar to other questions but those don't address using attributes like 'data-cfasync'. Mandalina and supra28 nailed it on the head.
It seems you are not adding your script tag correctly.
Here is one way you can do it:
const script = document.createElement("script");
script.type = "text/javascript";
script.src = "";
script.async = true;
script.dataset.cfasync = false;
document.body.appendChild(script);
script.addEventListener("load", () => {
console.log("Script added successfully");
resolve();
});
Try this function:
(function () {
if (typeof window.R === 'undefined') {
var s = document.createElement('script');
s.setAttribute('src', 'source goes here!');
document.body.appendChild(s); // this appends the script to the body you can also use document.head.appendChild(s) to append to the head
}
}());
I've been experimenting with metaprogramming in webpages, and need to delay a script tag from running until just after another script tag has been run. However, the script tag needs to be loaded first or both of them will fail.
Shortened and more readable version of what I'm trying to do:
<script defer>
w=function(){
<stuff that gives a parser error until modified by the next script tag>
}
</script>
<script>
<stuff that changes the previous script tag and any other script tags that ever will be added via the DOM
so it doesn't give a parser error>
</script>
<button onclick='w()'></button>
This would work perfectly well, except that the button's onclick attribute fails because the button was loaded before the first script tag was run.
Thanks in advance!
(EDIT: I linked a pastebin to show the full version of my code, it might clear things up a bit since it seems my summed-up version wasn't very good.
As suggested by #meagar in the comments, if you don't mind changing the type property of your "not actually javascript" script blocks you can do something like this:
<script type='derpscript'>
var derp;
var w=function(){alert('hello')};
derp||=5;
console.log(derp);
</script>
<script>
function compileDerps() {
// find all derpscript script tags
var x = document.querySelectorAll('script[type=derpscript]');
for(var i=0;i<x.length;i++){
meta=x[i].text
while(true){
pastmeta=meta;
console.log(exc=regex.exec(meta))
if(exc){
meta=meta.replace(regex,exc[1]+'='+exc[1]+'||');
}
if(pastmeta==meta){break;}
}
// make a new javascript script tag to hold the compiled derp
var s = document.createElement('script');
s.text = meta;
document.body.appendChild(s);
// delete the derpscript tag
x[i].parentNode.removeChild(x[i]);
}
}
//stuff that changes the previous script tag and any other script tags that ever will be added via the DOM
var regex=/([a-zA-Z$_][a-zA-Z$_1-9]*)(\|\|\=)/;
var meta;
var pastmeta='';
var exc='';
compileDerps();
</script>
<button onclick='w()'>THIS IS W</button>
This question already has answers here:
How do I include a JavaScript file in another JavaScript file?
(70 answers)
Closed 8 years ago.
The only way to fix it was using google chrome/IE10+ Just can't make it work on IE8.
I'm trying to append some Script to my web page, but i don't want to use any Jquery.
This DOES work, but it make use of jquery on the 3rd line.
var element = document.getElementById("contentSCRIPT");
element.parentNode.removeChild(element); // this removes the div and all the javascript inside it
$('<div id="contentSCRIPT"></div>').appendTo(document.getElementById("main")); // this adds again the content to the page
$('<script>' + document.getElementById("textSCRIPT").value + ' ;</' + 'script>').appendTo(document.getElementById("contentSCRIPT")); // in here i try to add the javascript code back to the content.
I tryied:
var content = document.createTextNode('<div id="contentSCRIPT"></div>');
document.getElementById("main").appendChild(content);
but it adds my script (content) as HTML not code.
any solutions?
Thanks!
Edit:
I have to create the contentScript cuz i want to delete the script from the page and add another multiple times.
I tryied
var contentScript = document.createElement("script");
contentScript.setAttribute("id", "contentSCRIPT");
document.getElementById('contentSCRIPT').innerHTML = document.getElementById('textoSCRIPT').value;
document.getElementById("main").appendChild(contentScript);
But again, this adds the code as an HTML (shows like a label on the page) and don't add to the DOM.
$('<div id="contentSCRIPT"></div>') can be written as follows in javascript:
var contentScript = document.createElement("div");
contentScript.setAttribute("id", "contentSCRIPT");
To do jQuery's appendTo, you want instead to appendChild on the parent:
document.getElementById("main").appendChild(contentScript);
Similarly, for the fourth line:
var script = document.createElement("script");
script.innerHTML = document.getElementById('textSCRIPT').value;
contentScript.appendChild(script);
EDIT
Based on your edited information, you don't need to create the div to hold the contentScript. Simply put an id on the script instead:
var contentScript = document.createElement("script");
contentScript.setAttribute("id", "contentSCRIPT");
contentScript.innerHTML = document.getElementById('textSCRIPT').value;
document.getElementById("main").appendChild(contentScript);
You can create a script element and append it to the document:
var script = document.body.appendChild(document.createElement('script'));
script.text = '/* CODE */';
As a response to your edit: You can remove a script element from the DOM, but you can't remove the script itself.
A live demo at jsFiddle.
var script = document.createElement("script");
var contentScript = document.createElement("div");
contentScript.setAttribute("id", "contentSCRIPT");
script.innerHTML = document.getElementById('textSCRIPT').value;
contentScript.appendChild(script);
You can add a script tag programatically by simply adding the script tag:
var scriptTag = document.getElementsByTagName("head")[0].appendChild(document.createElement("script"));
scriptTag.innerHTML = document.getElementById("textSCRIPT").value;
Change "head" to "body" if you want to add the script to the body.
I would like to place a Google tag manager script and according to Google Tag documentation, the script should be placed immediately after the opening tag.
Since we cannot change the source code, we have to append the script using the following code snippet.
<script type="text/javascript">
(function () {
var url = "path/to/js/file";
var gtm = document.createElement('script');
gtm.type = 'text/javascript';
gtm.async = true;
gtm.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + url;
var s = document.getElementsByTagName('body')[0];
s.parentNode.insertBefore(gtm, s);
})();
</script>
It is almost the same as Google analytics script snippet. Now the script is appended right before the body tag. I am not sure if using jQuery method insertAfter is the proper way to do it or if there is a better way!
I appreciate your kind help.
Actually your code inserts script between the head and body tags. Use this instead:
var s = document.body.firstChild;
s.parentNode.insertBefore(gtm, s);
You can use Node.insertBefore for this:
var body = document.getElementsByTagName("body")[0];
body.insertBefore(gtm, body.firstChild);
This works even if body tag has no firstChild.
This Q is not relevant anymore (DEC 2021), since GTM change the Setup and install of Tag Manager:
On the "new" setup you should:
Place the <script> code snippet in the <head> of your web page's HTML output, preferably as close to the opening <head> tag as
possible, but below any dataLayer declarations.
**Additionally - Place the <noscript> code snippet immediately after the tag in your HTML output.
https://support.google.com/tagmanager/answer/6103696
About <noscript> no meaning to add <noscript> by any Javascript code (noscript works only in browsers when JavaScript is off).
let html = '<p>Your HTML code here</p>';
document.body.insertAdjacentHTML('afterbegin', html);
The insertAdjacentHTML method allows you to insert an HTML string at a specified position relative to an element. In this case, we use 'afterbegin' to insert the HTML just after the opening tag.
I think you can try this out - appendChild
document.getElementsByTagName("body")[0].appendChild(gtm);
Try this:
var script = 'The script content here'; // Add your JS as a string,
var url = 'path/to/js/file'; // Or link to the file.
var scriptNode = document.createElement('script'); // Create a script Element
scriptnode.setAttribute('type', "text/javascript"); // Set the Element's `type` attribute.
// Either:
scriptNode.appendChild(document.createTextNode(script)); // Add the text to the script Element.
// Or:
scriptNode.setAttribute('src', url); // Link to the script
// Place the script Element before the first child of the body.
document.body.insertBefore(scriptNode , document.body.firstChild);
So, basically, use insertBefore
If you are utilizing jQuery, you may be able to use .prepend().
(function () {
var url = "path/to/js/file";
var gtm = document.createElement('script');
gtm.type = 'text/javascript';
gtm.async = true;
gtm.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + url;
$('body').prepend(gtm);
})();
Can you have an element in your body tag as first element, and append the script just before it. Use yourFirstElementIdfromBodyTag.before(here is your appended code goes) ..
For Example
<body>
<your first element> like <input type="hidden" id="hidA" />
//rest code goes here
</body>
Now as suggested use $('#hidA').before('the script code') . I am sure it will append the script just after <body>.
Lets suppose that I have the following markup:
<div id="placeHolder"></div>
and I have a JavaScript variable jsVar that contains some markup and some JavaScript.
By using Mootools 1.1 I can inject the JavaScript content into the placeholder like this:
$('placeHolder').setHTML(jsVar);
This works in Firefox, Opera, and even Safari and the resulting markup looks like this:
<div id="placeHolder">
<strong>I was injected</strong>
<script type="text/javascript">
alert("I was injected too!");
</script>
</div>
However, on IE 8 I get the following:
<div id="placeHolder">
<strong>I was injected</strong>
</div>
Is there any way to inject the JavaScript on IE 8 or does it security model forbid me from doing this at all?
I tried Luca Matteis' suggestion of using
document.getElementById("placeHolder").innerHTML = jsVar;
instead of the MooTools code and I get the same result. This is not a MooTools issue.
This MSDN post specifically addresses how to use innerHTML to insert javascript into a page. You are right: IE does consider this a security issue, so requires you to jump through certain hoops to get the script injected... presumably hackers can read this MSDN post as well as we can, so I'm at a loss as to why MS considers this extra layer of indirection "secure", but I digress.
From the MSDN article:
<HTML>
<SCRIPT>
function insertScript(){
var sHTML="<input type=button onclick=" + "go2()" + " value='Click Me'><BR>";
var sScript="<SCRIPT DEFER>";
sScript = sScript + "function go2(){ alert('Hello from inserted script.') }";
sScript = sScript + "</SCRIPT" + ">";
ScriptDiv.innerHTML = sHTML + sScript;
}
</SCRIPT>
<BODY onload="insertScript();">
<DIV ID="ScriptDiv"></DIV>
</BODY>
</HTML>
If at all possible, you may wish to consider using a document.write injected script loading tag to increase security and reduce cross-browser incompatibility. I understand this may not be possible, but it's worth considering.
This is how we did it on our site about a year ago to get it working in IE. Here are the steps:
add the HTML to an orphan DOM element
search the orphan node for script tags (orphan.getElementsByTagName)
get the code from those script nodes (save for later), and then remove them from the orphan
add the html leftover that is in the orphan and add it to the placeholder (placeholder.innerHTML = orphan.innerHTML)
create a script element and add the stored code to it (scriptElem.text = 'alert("my code");')
then add the script element to the DOM (preferably the head), then remove it
function set_html( id, html ) {
// create orphan element set HTML to
var orphNode = document.createElement('div');
orphNode.innerHTML = html;
// get the script nodes, add them into an arrary, and remove them from orphan node
var scriptNodes = orphNode.getElementsByTagName('script');
var scripts = [];
while(scriptNodes.length) {
// push into script array
var node = scriptNodes[0];
scripts.push(node.text);
// then remove it
node.parentNode.removeChild(node);
}
// add html to place holder element (note: we are adding the html before we execute the scripts)
document.getElementById(id).innerHTML = orphNode.innerHTML;
// execute stored scripts
var head = document.getElementsByTagName('head')[0];
while(scripts.length) {
// create script node
var scriptNode = document.createElement('script');
scriptNode.type = 'text/javascript';
scriptNode.text = scripts.shift(); // add the code to the script node
head.appendChild(scriptNode); // add it to the page
head.removeChild(scriptNode); // then remove it
}
}
set_html('ph', 'this is my html. alert("alert");');
I have encountered the same issues with IE8 (and IE7)
The only way I could dynamically inject a script (with an src) is by using a timer:
source = "bla.js";
setTimeout(function () {
// run main code
var s = document.createElement('script');
s.setAttribute('src', source);
document.getElementsByTagName('body')[0].appendChild(s);
}, 50);
If you have inline code you would like to inject, you can drop the timer and use the "text" method for the script element:
s.text = "alert('hello world');";
I know my answer has come pretty late; however, better late than never :-)
I am not sure about MooTools, but have you tried innerHTML ?
document.getElementById("placeHolder").innerHTML
= jsVar;
You may need to eval the contents of the script tag. This would require parsing to find scripts in your jsVar, and eval(whatsBetweenTheScriptTags).
Since IE refuses to insert the content by default you will have to execute it yourself, but you can at least trick IE into doing the parsing for you.
Simply use string.replace() to swap all the <script> tags for <textarea class="myScript" style="display:none">, preserving the content. Then stick the result into an innerHTML of a div.
After this is done, you can use
div.getElementsByTagName("textarea")
to get all the textareas, loop through them and look for your marker class ("myScript" in this case), and either eval(textarea.value) or (new Function(textarea.value))() the ones you care about.
I never tried it, it just came to my mind... Can you try the following:
var script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = '//javascript code here'; // not sure if it works
// OR
script.innerText = '//javascript code here'; // not sure if it works
// OR
script.src = 'my_javascript_file.js';
document.getElementById('placeholder').appendChild(script);
You can use the same technique (DOM) to insert HTML markup.
I am sorry, perhaps I am missing something here--but with this being a mootools 1.11 question, why don't you use assets.js?
// you can also add a json argument with events, etc.
new Asset.javascript("path-to-script.js", {
onload: function() {
callFuncFromScript();
},
id: "myscript"
});
Isn't one of the reasons why we're using a framework not to have to reinvent the wheel all over again...
as far as the 'other' content is concerned, how do you happen to get it? if through the Request class, it can do what you want nicely by using the options:
{
update: $("targetId"),
evalScripts: true,
evalResponse: false
}
When you say it "works" in those other browsers, do you mean you get the alert popup message, or do you just mean the <script> tag makes it into the DOM tree?
If your goal is the former, realize that the behaviour of injecting html with embedded <script> is very browser-dependent. For example in the latest MooTools I can try:
$(element).set('html', '<strong>Foo</strong><script>alert(3)</script>')
and I do not get the popup, not in IE(7), not in FF(3) (however I do get the <script> node into the DOM successfully). To get it to alert in all browsers, you must do as this answer does.
And my comment is really late, but it's also the most accurate one here - the reason you're not seeing the <script> contents running is because you didn't add the defer attribute to the <script> tag. The MSDN article specifically says you need to do that in order for the <script> tag to run.