4

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 attempt to click the button.

Is this expectable, and if so is there a workaround?

5
  • 1
    Yes, that should work, assuming you're doing it right. Post the code & we'll let you know... Commented Dec 12, 2009 at 1:57
  • 1
    Did you view the page source and verify that the function is actually inserted as you expect? Commented Dec 12, 2009 at 1:58
  • It depends on your definition of "dynamically inserted". Define this please. Commented Dec 12, 2009 at 1:58
  • 1
    @Crescent Fresh: it's fairly obvious to me what he means - how many different ways can you define dynamically inserted? Commented Dec 12, 2009 at 2:11
  • Firebug shows the <script> tag, and when I click "Edit HTML..." the JavaScript shows up fine Commented Dec 12, 2009 at 2:16

3 Answers 3

9

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]

Sign up to request clarification or add additional context in comments.

1 Comment

I'm using the DOM method. Thanks.
1

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.

5 Comments

Is it just me that doesn't particularly appreciate getting answers like "use xxx library"? What if he's only writing 5 lines of code, is it really worth the browser downloading and parsing a library to perform a simple function?
I actually am a jQuery user, however for this specific instance I do not want to use a library
As am I, it's just that there are a number of scenarios where cross-browser compatibility is not needed (intranets, desktop widgets, etc) and whilst libraries can still make things easier they might sometimes be overkill. I do wonder if some people know javascript outside of libraries...
AndyE, I actually agree with you here - having someone tell you "use a library" often isn't very helpful. However in this particular answer I was speaking purely from experience, and jQuery was what I used to solve the problem; I wasn't aware that the DOM based alternative worked, to be perfectly honest. At the time there was no answer, so I figured one using jQuery was better than none at all.
Don't mind me, it was 2am and I had my grumpy head on :-) I remember, you got your answer out while I was still writing mine and I agree, an answer is an answer at the end of the day and jQuery is always a suitable option for most devs.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.