How to dynamically insert a <script> tag via jQuery after page load?
Asked Answered
I

9

117

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?

Inexpugnable answered 4/10, 2010 at 18:2 Comment(8)
Can you explain what it is you're trying to achieve by adding a <script> tag to the document?Permissible
@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.Janeljanela
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.Inexpugnable
In that case Rocket's answer is definitely what you want.Janeljanela
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.Irritative
@Irritative - yes, i did manage to once get this to work but noticed the page seemed to get reloaded and just display the ad. it seems you might be right, their script has a few .write methods. so essentially, when these scripts are in the page loading along with it, they just output the ad code within the page, but if loaded after page load, they overwrite the page completely instead?Inexpugnable
Why not import those tags in <iframe> elements? You can defer setting the <iframe> URL until you're ready.Permissible
Perhaps worth noting that here in 2023 all browsers default the type so we no longer need the type="text/javascript" for <script tags.Leela
R
110

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");
});
Ratepayer answered 4/10, 2010 at 18:5 Comment(10)
thanks, but will that stick it into the DOM? i realize i left out that important info, that i need the script tag to be inserted into the DOM, evaluated, at which point it returns 3rd party ad code to display on our site in a specific <div>.Inexpugnable
$.getScript will just load a .js file via AJAX and execute it. The script doesn't need to be in the DOM to be able to access a div on your page.Ratepayer
But with $.getScript() the script will need to be on the same domain or both the remote domain and the browser will need to support CORS.Ideal
@Ideal That's actually not true. It just inserts a plain ol' script tag, which doesn't require CORS or same-domain. I use this to shorten the code for loading Google Analytics for example, and it loads just fine. Behind the scenes the actual jquery code that runs is pretty similar to the GA snippet, in fact.Golfer
@ChrisMoschini: Hmm I can't remember back when I commented on this. I don't actually used $.getScript() but don't want to delete my comment since it now has four upvotes...Ideal
Since the answer from @Ideal will attract the most attention with its 4 upvotes, it should be made emphatically clear that he is incorrect. As the jQuery docs highlight in their $.ajax notes: "Script and JSONP requests are not subject to the same origin policy restrictions." source. In other words, $.getScript can pull .js files from other domains, not just your own.Bioluminescence
Another nice trick is to use chaining and run $.getScript(url).done(function(script, textStatus) { console.log('done')}).fail(function(jqxhr, settings, exception) { console.log('error')});Chiasma
This is overly complicated as it requires a separate .js file when all the OP wants to do is inject some script into the DOM.Chukar
@RocketHazmat, just a question, it is also possible to use this for a CDN script? e.g. cdnjs.cloudflare.com/ajax/libs/waypoints/2.0.3/waypoints.min.jsScandalmonger
@Franco: Yes, you can do $.getScript('http://cdnjs.cloudflare.com/ajax/libs/waypoints/2.0.3/waypoints.min.js');.Ratepayer
C
73

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

Cadent answered 4/10, 2010 at 18:23 Comment(6)
+1 for use of append to add a script. Append causes even inline script to evaluate immediately (just what I needed). ThanksSkink
I end up having a lot of issues in IE8/9 with this approach. Namely Stack Overflow errors. I resorted to the $.getScript() method below to have this work across the board.Chiasma
Yes @Chukar this was written in October 2010 :)Cadent
If the page containing this code is loaded using AJAX, the browser will throw a "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience" warning.Scathe
@Reddy Great comment. This was posted in October 2010, I'm sure by now this method is no longer a valid/recommended approach, users have to proceed at their own discretion.Cadent
Does this solution work if the injected javascript is using document.write? I ask this because most ad related javascripts we get from customers are using it.Edmondo
C
43

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');
});
Chukar answered 23/11, 2014 at 21:43 Comment(2)
Or instead .text('some script here') you can write .attr('src', 'path_to_your_js_file')Daigle
Thank you very much @Chukar this syntax is useful for me.Cruel
B
14

A simpler way is:

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

You can also use this form to load css.

Bethsaida answered 20/2, 2015 at 9:59 Comment(2)
You might want to avoid putting the string </script> in your source though since it may cause parsing problems: #236573Cholesterol
escaping the last / did the trick for me: $('head').append('<script src="your.js"><\/script>');Fatalism
C
6

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'));
}
Caudad answered 14/3, 2016 at 13:1 Comment(1)
btw. I do the same with stylesheets: if (!$('head > link[href="widgets/css/widgets.css"]').length) {$('head').append($('<link />').attr('rel','stylesheet').attr('href','widgets/css/widgets.css'));}Caudad
N
5

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.

Note: it willl cancel declared event listeners.

Nicki answered 29/6, 2017 at 23:39 Comment(1)
This kills all events on page, because it turns the page to string and back.Venipuncture
R
2

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!

Radioluminescence answered 22/5, 2015 at 11:24 Comment(0)
T
1

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.

Theodora answered 15/12, 2012 at 3:48 Comment(4)
It will not work if the closing script tag is in one piece as the browser sees it as the closing tag for your script instead of a string literal.Skink
<\/script> would be valid thoughNitrogenize
I think @TrueBlueAussie's point was in response to your comment "Just don't ask me why...but interestingly enough, it will NOT work if you append the closing tag in one line." He explained why so that any readers who would like a better answer than "I don't know" could more easily find it. See also: javascript.crockford.com/script.htmlCholesterol
@Sathvik is correct, according to that link. Ash's comment seems to have been a reply to one that got removed.Playoff
P
-4

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.

Peshitta answered 4/10, 2010 at 18:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.