41

I want to add a element into the existing DOM to have the javascript code run.

I did this with YUI:

var scriptNode = Y.Node.create('<script type="text/javascript" charset="utf-8">alert("Hello world!");<\/script>');
var headNode = Y.one('head');
headNode.append(scriptNode);

It's successfully added to the DOM but it doesn't give me an alert.

Someone knows what the problem is?

4
  • Any reason why you don't run the JS directly? Commented Jun 21, 2011 at 23:08
  • Is the Javascript in scriptNode under your control? Wrap it in a function and call it after appending it? Just found this - seems appropriate and informative: stackoverflow.com/questions/610995/… Commented Jun 21, 2011 at 23:22
  • Your closing tag has an extra '\', it should be </script>, not sure if this effects it Commented Jun 22, 2011 at 0:03
  • 1
    SharpPer - the backslash quotes the following forward slash so that </ in the string isn't mistaken for the closing tag of the enclosing script element. It is consdered good practice for closing tags in string literals. Commented Jun 22, 2011 at 0:25

2 Answers 2

93

I have no idea how YUI's Node.create() function works, so no comment on that. But a simple cross-browser script is:

  window.onload = function() {
    var s = document.createElement('script');
    s.type = 'text/javascript';
    var code = 'alert("hello world!");';
    try {
      s.appendChild(document.createTextNode(code));
      document.body.appendChild(s);
    } catch (e) {
      s.text = code;
      document.body.appendChild(s);
    }
  }

The try..catch block is necessary as most browsers like the first method but some don't and throw an error. The second method covers those. You can also simply eval the code, which is more or less equivalent and what some libraries do.

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

6 Comments

Can't you put document.body.appendChild(s) under a finally clause?
Yes, that's fine as the error is caused by appending the text node to a script element.
If the catch block code satisfies more browsers, then why not simply use that?
Note that if you eval the code instead of adding a script element, document.currentScript will not be set properly. If you are making a tool for other people to use, their script code might depend on document.currentScript
Why can't you just use the second method then? Some browsers don't work with the second method?
|
13

I found this function in the JQuery source, which seems to do what you want and feels a bit cleaner than the other approaches to me. But then again I am a JS beginner and probably don't see the details. Anyways, somebody might take something useful away from this.

function DOMEval( code, doc ) {
    doc = doc || document;

    var script = doc.createElement( "script" );

    script.text = code;
    doc.head.appendChild( script ).parentNode.removeChild( script );
}

3 Comments

What is with the removeChild call? Wouldn't that remove the script you just added? Is there a trick I'm missing?
@Danger It appends the code in a script tag, it executes immediately, then the script tag is removed to clean up. The function is called DOMEval, not addScript, etc.
Using the createTextNode was appending the code as a string. Your solution of adding the code via the text property was the good one for me.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.