Run custom javascript from dynamicaly loaded innerHTML context - javascript

I have an HTML document
...
<div id="test"></div>
...
Then i dynamicaly load some context to #test div.
function change()
{
ws = document.getElementById(id);
str = '<script>function ttest(){window.alert("Yahoo!!!")}</script><select><option onclick="ttest();">1</option><option >2</option></select>';
ws.innerHTML = str;
}
window.onload = change();
When the page is loaded a custom script
<script>function ttest(){window.alert("Yahoo!!!")}</script>
doesnt work.
It works perfect when its put static without any innerHTML.
Also it works when its not a custom function.
How can i make my custom function work, when it was loaded dynamically using innerHTML or/and AJAX+innerHTML ?

Add your script to the document.head via createElement. So something like this:
var script = document.createElement("script");
script.innerHTML = "function ttest() { alert('Yahoo'); }";
document.head.appendChild(script)

Related

Writing to a script tag after page loads

<script>
document.querySelector( 'html' ).innerHTML += 'hello';
</script>
<script>
document.querySelector( 'script' ).innerHTML += 'alert( "world?" )';
</script>
The alert() function does not fire on page load. This is an overly simplified example but the desired result is to inject additional JavaScript code into a script tag after the page has loaded.
How can this code be altered so that the alert function properly fires in the browser?
If you have jQuery, you can just use:
$(document).ready(function() {
$.getScript("http://jact.atdmt.com/jaction/JavaScriptTest");
});
In plain javascript, you can load a script dynamically at any time like this:
var tag = document.createElement("script");
tag.src = "http://jact.atdmt.com/jaction/JavaScriptTest";
document.getElementsByTagName("head")[0].appendChild(tag);
This won't work because the HTML spec doesn't allow for scripts inserted using innerHTML to be executed.
script elements inserted using innerHTML do not execute when they are inserted.
What you can instead do is use the document.createTextNode() method to insert your script body.
<script>
document.querySelector( 'html' ).innerHTML += 'hello';
const scriptTag = document.createElement("script");
const scriptNode = document.createTextNode("alert('Hello World!');");
scriptTag.appendChild(scriptNode);
document.body.appendChild(scriptTag);
</script>

Place a script immediately after the opening <body> tag

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>.

What alternatives are there to document.write?

I'm trying to load a zoom.it script dynamically, but I can't seem to do so without document.write. The problem with document.write is that it replaces everything on my page, which I don't want. What other alternatives are there?
This is document.write in action: http://jsfiddle.net/JyT9B/6/ (notice the element that gets removed).
Also, putting the <script> tag straight into the body works: http://jsfiddle.net/gTcRw/5/, but I need it to be dynamically placed.
I've also tried the methods in Ways to add javascript files dynamically in a page, and How to add and remove js files dynamically, but seem to get the error Cannot set property 'innerHTML' of null, which is probably a zoom.it specific thing. I wouldn't mind knowing why this is the case.
The jsfiddle examples of using the other approaches:
$('body').append
$.getScript
document.createElement as per google analytics
document.createElement in a function
Also tried this in vain: .innerHTML - it gets added to the dom but isn't run.
I think the combination of createElement and appendChild should work, in something like this:
http://jsfiddle.net/kbDny/3/
$(function() {
getScript("http://www.zoom.it/aaa.js");
});
function getScript(src) {
var scr = document.createElement("script");
scr.type = "text/javascript";
scr.src = src;
var head = document.getElementsByTagName("head")[0];
head.appendChild(scr);
}
But there's no reason to not use $.getScript - just pass the url as the first argument, like:
$.getScript(url, function (data, textStatus, jqxhr) {
// Script loaded successfully
});
Ended up using an iframe to contain a html page with an embedded script tag.
The benefit of an iframe is that I can show/remove it at will, without having to worry about cleaning up the current page document when removing the script.
ie,
HTML
<body>
<div id="container">
<a id="show" href="#">show</a>
<a id="close" href="#">close</a>
<div id="placeholder"></div>
</div>
</body>​
JavaScript
function appendFrame(elem) {
var iframe = document.createElement("iframe");
iframe.id = "iframe";
iframe.setAttribute("src", "about:blank");
iframe.style.width = "200px";
iframe.style.height = "200px";
$(elem).append(iframe);
}
function loadIFrame() {
appendFrame($("#placeholder"));
var doc = document.getElementById('iframe').contentWindow.document;
doc.open();
doc.write("<html><head><title></title></head><body><script src='http://zoom.it/aaa.js'><\/script><\/body><\/html>");
doc.close();
};
$("#show").click(function() {
loadIFrame();
});
$("#close").click(function() {
$("#iframe").remove();
});​
JSFiddle solution here: http://jsfiddle.net/7KRcG/2/

Add jquery script via script file

I have script (myscript.js) which create div and animate div in any HTML page. my script is using Jquery animation function
I am currently using following code (it's sample snippet)
<script src="jquery.js"><script>
<script src="myscript.js"><script>
But is this possible to use only following code which can automatically add JQuery library also?
<script src="myscript.js"><script>
Insert this on top of your myscript.js
var h=document.getElementsByTagName('head')[0];
var s=document.createElement('script');
s.type='text/javascript';
s.src='http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js';
h.appendChild(s);
but you will have to wait until script loaded using waitforload function
function w4l(){
if (typeof jQuery != "function"){
setTimeout("w4l()", 1000);
return;
}else{
//Do Jquery thing
}
}
w4l();
or just simply copy all jquery.js code file into your myscript.js, AKA merge 2 file into one
To make sure that the rest of myscript.js doesn't get executed before jQuery is loaded, use something like this:
function dostuff() {
//animate elements, etc.
}
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'jquery.js';
script.onreadystatechange = dostuff;
script.onload = dostuff;
head.appendChild(script);
Note: it's a bit unclear why you wouldn't want to explicitly add the jQuery part in your head.

How to dynamically insert jquery code

I am trying use jQuery's rich animation features on dynamically loaded content.
I can dynamically insert script into an element like so:
var element = document.createElement("div");
element.innerHTML = "some html here";
var script = document.createElement("script");
script.type = "text/javascript";
script.text = 'alert("Alert!");';
element.appendChild (script);
The problem occurs when I try to insert jquery code into the script element. This does not work and causes the script to not run at all.
var element = document.createElement("div");
element.innerHTML = "some html here";
var script = document.createElement("script");
script.type = "text/javascript";
script.text = 'alert("Alert!");\n';
script.text = script.text+'$("div").animate({height:300,opacity:0.4},"slow");\n';
element.appendChild (script);
I can successfully append javascript code to change the elements I want, but using jquery functions will simplify things.
With firebug I can see the script elements has been loaded into the dom, however when I add the jquery code to it, nothing happens, not even the alert.
I have included the jquery source file in my main document and wrapped all of my code into a window.addEventListener('load', function()) to call the functions that initiates the code above when the page finishes loading.
Is there a way to dynamically create calls to jquery functions? Am I going about this the right way? I've been stumped for a while and google hasnt solved this one for me, any help is appreciated.
This should do what you want:
$('body').append('<s' + 'cript>console.log("lol");</script>');
But why are you not wrapping your code into a function which you can then call whenever you please?
function iAnimateThings() {
$("div").animate({height:300,opacity:0.4},"slow");
}
hey nothing wrong with your code you just missed one single inverted comma on this line
script.text = script.text+'$("div").animate({height:300,opacity:0.4},"slow")';
here is your working fiddle
http://jsfiddle.net/vYut9/

Categories

Resources