Executing script injected by innerHTML after AJAX call
JavaScript inserted as DOM text will not execute. However, you can use the dynamic script pattern to accomplish your goal. The basic idea is to move the script that you want to execute into an external file and create a script tag when you get your Ajax response. You then set the src
attribute of your script tag and voila, it loads and executes the external script.
This other StackOverflow post may also be helpful to you: Can scripts be inserted with innerHTML?.
Starting newly-inserted script after AJAX call and stopping removed script after another AJAX call
You can wrap around the setTimeout
before eval()
the script. When removed the script, you can unregister the tasks.
function mockInternal() {
const setTimeout = window.setTimeout;
const setInterval = window.setInterval;
// window.setImmediate
// window.addEventListener
const setTimeoutHandlers = [];
const setIntervalHandlers = [];
window.setTimeout = function mock_setTimeout(callback, delay) {
const h = setTimeout(callback, delay);
setTimeoutHandlers.push(h);
return h;
}
window.setInterval = function mock_setInterval(callback, delay) {
const h = setInterval(callback, delay);
setIntervalHandlers.push(h);
return h;
}
return function clearMockInternal() {
window.setTimeout = setTimeout;
window.setInterval = setInterval;
setTimeoutHandlers.forEach(h => clearTimeout(h));
setIntervalHandlers.forEach(h => clearInterval(h));
}
}
const clearMockInternal = mockInternal();
eval(`setInterval(() => console.log(new Date()), 1000);`);
setTimeout(() => {
clearMockInternal();
console.log("should not log Date from now");
}, 6000);
Executing script elements inserted with .innerHTML
The OP's script doesn't work in IE 7. With help from SO, here's a script that does:
exec_body_scripts: function(body_el) {
// Finds and executes scripts in a newly added element's body.
// Needed since innerHTML does not run scripts.
//
// Argument body_el is an element in the dom.
function nodeName(elem, name) {
return elem.nodeName && elem.nodeName.toUpperCase() ===
name.toUpperCase();
};
function evalScript(elem) {
var data = (elem.text || elem.textContent || elem.innerHTML || "" ),
head = document.getElementsByTagName("head")[0] ||
document.documentElement,
script = document.createElement("script");
script.type = "text/javascript";
try {
// doesn't work on ie...
script.appendChild(document.createTextNode(data));
} catch(e) {
// IE has funky script nodes
script.text = data;
}
head.insertBefore(script, head.firstChild);
head.removeChild(script);
};
// main section of function
var scripts = [],
script,
children_nodes = body_el.childNodes,
child,
i;
for (i = 0; children_nodes[i]; i++) {
child = children_nodes[i];
if (nodeName(child, "script" ) &&
(!child.type || child.type.toLowerCase() === "text/javascript")) {
scripts.push(child);
}
}
for (i = 0; scripts[i]; i++) {
script = scripts[i];
if (script.parentNode) {script.parentNode.removeChild(script);}
evalScript(scripts[i]);
}
};
Can scripts be inserted with innerHTML?
You have to use eval() to execute any script code that you've inserted as DOM text.
MooTools will do this for you automatically, and I'm sure jQuery would as well (depending on the version. jQuery version 1.6+ uses eval
). This saves a lot of hassle of parsing out <script>
tags and escaping your content, as well as a bunch of other "gotchas".
Generally if you're going to eval()
it yourself, you want to create/send the script code without any HTML markup such as <script>
, as these will not eval()
properly.
script tag is shown in ajax response and executed?
By default, the <script>
tag is meant to have display: none
using the User Agent Stylesheet:
I strongly believe if you inspect the element, you will find that in the Computed Styles as I shown above, it will be inheriting display
styles somehow. That's the reason.
Find something like:
.divClass * {display: block;}
Coz, no one targets <script>
tag! :P
Related Topics
Why Isn't My JavaScript Working in Jsfiddle
Using Jquery to Center a Div on the Screen
Custom Attributes - Yea or Nay
Hide Text in HTML Which Does Not Have Any HTML Tags
Jquery: Get Height of Hidden Element in Jquery
How to Save Canvas as an Image With Canvas.Todataurl()
Avoid Dropdown Menu Close on Click Inside
How to Scroll to an Element Using JavaScript
Change :Hover CSS Properties With JavaScript
What Is Offsetheight, Clientheight, Scrollheight
How to Modify Style to HTML Elements (Styled Externally With Css) Using Js
Maximum Call Stack Size Exceeded Error
How to Specify a Suggested Filename When Using Data: Uri
How Can JavaScript Upload a Blob
Adjust Width of Input Field to Its Input
Launch Bootstrap Modal on Page Load
Browser/Html Force Download of Image from Src="Data:Image/Jpeg;Base64..."