Reputation: 4326
I have a javascript variable:
var foo='<script type="text/javascript">alert("Hello World");<\/script>'
The variable is inserted with element.innerHTML=foo; after an event occurs on the page, about 10 seconds after the page is loaded.
Is there a way to execute the 'alert' function right after the insertion?
Upvotes: 3
Views: 3065
Reputation: 1074028
If you absolutely, positively have to take JavaScript code that's in a string and execute it, you basically have to use eval
or an eval
-like mechanism. In some years of JavaScript programming, I've never had to resort to it, and I do suggest that you look at whether there's another way to achieve your actual overall goal.
So here, you'd strip off the script tag stuff and just eval
the code, e.g.:
var script = foo.replace(/^<script[^>]*>/, "").replace(/<\/script>$/, "");
eval(script);
// Or window.evalInGlobalScope(script); // -- See below
Obviously you have to be sure you trust the source of the string, since you're executing the code therein.
eval
is a slippery beast and plays very odd games with context and scope. If you need something that looks more like what you'd get if you did add a script tag to the page, here's a function that does that cross-browser (from my answer to this other question here on Stack Overflow):
window.evalInGlobalScope = (function() {
var fname, scr;
// Get a unique function name
do {
fname = "__eval_in_global_test_" + Math.floor(Math.random() * 100000);
}
while (typeof window[fname] !== 'undefined');
// Create test script
scr = "function " + fname + "() { }";
// Return the first function that works:
return test(evalInGlobalScope_execScript) ||
test(evalInGlobalScope_windowEval) ||
test(evalInGlobalScope_theHardWay) ||
evalInGlobalScope_fail;
function test(f) {
try {
f(scr);
if (typeof window[fname] === 'function') {
return f;
}
}
catch (e) {
return false;
}
finally {
try { delete window[fname]; } catch (e) { window[fname] = undefined; }
}
}
function evalInGlobalScope_execScript(str) {
window.execScript(str);
}
function evalInGlobalScope_windowEval(str) {
window.eval(str);
}
function evalInGlobalScope_theHardWay(str) {
var parent, script, d = document;
parent = d.body || d.documentElement || d.getElementsByTagName('head')[0];
if (parent) {
script = d.createElement('script');
script.appendChild(d.createTextNode(str));
parent.appendChild(script);
}
}
function evalInGlobalScope_fail() {
throw "evalInGlobalScope: Unable to determine how to do global eval in this environment";
}
})();
Upvotes: 5
Reputation: 66389
You don't need to make lots of changes, just one small change.
Right now you have such line of code:
oDiv.innerHTML = foo;
Just change it to those three lines instead:
var oScript = document.createElement("script");
oScript.innerHTML = foo;
oDiv.appendChild(oScript);
And have foo
contain only the raw JS, without the <script>
and </script>
tags.
Upvotes: 0