106
votes

I'm having problems getting this to work. I first tried setting my script tags as strings and then using jquery replaceWith() to add them to the document after page load:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

But I got string literal errors on that var. I then tried encoding the string like:

var a = '&left;script type="text/javascript"&gt;some script here&lt;\/script&gt;';

but sending that to replaceWith() outputs just that string to the browser.

Can someone please let me know how you would go about dynamically adding a <script> tag into the browser after page load, ideally via jQuery?

9
Can you explain what it is you're trying to achieve by adding a <script> tag to the document? - Pointy
@Rocket's answer is the best, but if you definitely wanted to add inline script from a string, then you would just pass it to the eval() function. But use of eval() almost always suggests that there's a better way of doing what you are trying to do. - Nick
we're trying to postpone loading of 3rd party ads until the end of the page. those ads get called via 2 script tags, so i wanted to run a function after page load that throws them in dynamically. - Doug
Not all third-party scripts are designed to be deferrable. If the script uses document.write and you call it after page loading it will destroy the page. - bobince
Why not import those tags in <iframe> elements? You can defer setting the <iframe> URL until you're ready. - Pointy

9 Answers

106
votes

You can put the script into a separate file, then use $.getScript to load and run it.

Example:

$.getScript("test.js", function(){
    alert("Running test.js");
});
68
votes

Try the following:

<script type="text/javascript">
// Use any event to append the code
$(document).ready(function() 
{
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.src = "http://scriptlocation/das.js";
    // Use any selector
    $("head").append(s);
});

http://api.jquery.com/append

39
votes

Here's the correct way to do it with modern (2014) JQuery:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .appendTo('head');
})

or if you really want to replace a div you could do:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .replaceAll('#someelement');
});
12
votes

A simpler way is:

$('head').append('<script type="text/javascript" src="your.js"></script>');

You can also use this form to load css.

5
votes

This answer is technically similar or equal to what jcoffland answered. I just added a query to detect if a script is already present or not. I need this because I work in an intranet website with a couple of modules, of which some are sharing scripts or bring their own, but these scripts do not need to be loaded everytime again. I am using this snippet since more than a year in production environment, it works like a charme. Commenting to myself: Yes I know, it would be more correct to ask if a function exists... :-)

if (!$('head > script[src="js/jquery.searchable.min.js"]').length) {
    $('head').append($('<script />').attr('src','js/jquery.searchable.min.js'));
}
4
votes

Here is a much clearer way — no need for jQuery — which adds a script as the last child of <body>:

document.body.innerHTML +='<script src="mycdn.js"><\/script>'

But if you want to add and load scripts use Rocket Hazmat's method.

2
votes

Example:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

It should work. I tried it; same outcome. But when I used this:

var length = 1;
var html = "";
for (var i = 0; i < length; i++) {
    html += '<div id="codeSnippet"></div>';
    html += '<script type="text/javascript">';
    html += 'your script here';
    html += '</script>';
}
$('#someElement').replaceWith(a);

This worked for me.

Edit: I forgot the #someelement (btw I might want to use #someElement because of conventions)

The most important thing here is the += so the html is added and not replaced.

Leave a comment if it didn't work. I'd like to help you out!

1
votes

There is one workaround that sounds more like a hack and I agree it's not the most elegant way of doing it, but works 100%:

Say your AJAX response is something like

<b>some html</b>
<script>alert("and some javscript")

Note that I've skipped the closing tag on purpose. Then in the script that loads the above, do the following:

$.ajax({
    url: "path/to/return/the-above-js+html.php",
    success: function(newhtml){
        newhtml += "<";
        newhtml += "/script>";
        $("head").append(newhtml);
    }
});

Just don't ask me why :-) This is one of those things I've come to as a result of desperate almost random trials and fails.

I have no complete suggestions on how it works, but interestingly enough, it will NOT work if you append the closing tag in one line.

In times like these, I feel like I've successfully divided by zero.

-4
votes

If you are trying to run some dynamically generated JavaScript, you would be slightly better off by using eval. However, JavaScript is such a dynamic language that you really should not have a need for that.

If the script is static, then Rocket's getScript-suggestion is the way to go.