I have some code where a <script type="text/javascript">
block is dynamically inserted.
This block contains a function, which has an <input type="button">
element above it (also dynamically inserted) call it with the onclick
attribute.
However, it is not working, and Firebug says that the function is not defined when I at开发者_JS百科tempt to click the button.
Is this expectable, and if so is there a workaround?
If you're writing it to an innerHTML property, it won't work except for in IE when the DEFER attribute is present:
scriptParentNode.innerHTML = '<span/><script defer="defer" type="text/javascript">blah();</script>';
Your options are, a) use the DOM to create the element and append it:
var head = document.getElementsByTagName("head")[0];
var sTag = document.createElement("script");
sTag.type = "text/javascript";
sTag.text = "blah();";
head.appendChild(sTag);
or b) use document.write at the time your HTML is parsed (but not after!)
<head>
<script type="text/javascript">
document.write('<script type="text/javascript">blah();</script>');
</script>
</head>
EDIT
Seeing as I was downvoted apparently for the information regarding the defer attribute being incorrect, I feel it necessary to post a working example from the MSDN documentation. Whilst it is true that IE removes NoScope elements from the beginning of an innerHTML string, it's possible to work around this by adding a scoped element to the beginning of the HTML string (example updated above):
<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>
Feel free to actually click the "Show me" button in the MSDN documentation for a working example. [link]
If you're using something like
document.getElementById('foo').innerHTML = blah
then no, it won't work.
An easy workaround is to use jQuery to do your insertion, which will execute the script in that block. Just use the html
function on an element, passing it your HTML/script block.
Dynamically inserted client-side or server-side?
Server-side it'll work - assuming that the server-side call isn't an AJAX postback (Cause then in reality the actual dynamic insertion is still client-side).
Client-side it won't (you can't simply inject java-script into a page after it's already loaded and expect it to execute). You'll have to actually explicitly execute the JavaScript in that case or use a framework like jQuery that'll do that for you.
精彩评论