0

I am trying to load script dynamically. This is my code:

document.write('<script type="text/javascript">window.jQuery || document.write(\"<script src=\'http://code.jquery.com/jquery-1.10.2.min.js\'></script>\")</script>');

This is inside B.js which is loaded as script on A.html. But I get error. The end script tag inside double quotes is treated as if it's nested script tag and breaking the code.

Any ideas how to fix this?

Jack
  • 7,433
  • 22
  • 63
  • 107
  • 3
    Yea, don't use `document.write()`. Use DOM manipulation instead. – Cerbrus Feb 12 '14 at 13:44
  • @Cerbrus you cannot executable script into DOM – Yuriy Galanter Feb 12 '14 at 14:15
  • 1
    @YuriyGalanter: _"cannot executable script into DOM"_ --> cannot what? "Run"? "Insert"? Either way, you won't need to. instead of the `document.write`, just check for jQuery. if jQuery doesn't exist, use DOM manipulation to load the script. – Cerbrus Feb 12 '14 at 14:19

4 Answers4

5

use:

var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://somedomain.com/somescript";
    $("head").append(s);
//or using plain js
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(s);

dynamically-load-jquery-library-javascript

Milind Anantwar
  • 81,290
  • 25
  • 94
  • 125
  • 3
    I like how you were _vanilla_ up to `$("head")` xD [`document.head`](https://developer.mozilla.org/en-US/docs/Web/API/document.head) – Paul S. Feb 12 '14 at 13:46
  • _"jQuery handles tags in a special way"_ Nope. The inner `` tag is simply breaking the code. Other than that, the solution is correct. – Cerbrus Feb 12 '14 at 13:47
  • hmm.i guess i did not explained that part properly. – Milind Anantwar Feb 12 '14 at 13:49
  • @PaulS.:Beauty of jquery..... :D – Milind Anantwar Feb 12 '14 at 13:49
  • 1
    the beauty is invalid for me because jquery is what I am trying to load dynamically if you see my code :S – Jack Feb 12 '14 at 13:50
  • @Jack:updated the answer. use javascript solution. – Milind Anantwar Feb 12 '14 at 13:52
  • That would work but not in my case. The problem here is I have js1.js which is script file below your posted code. js1.js has all jquery functions. When we load jquery like the code you posted the browser loads js1.js first and loads jquery.js after that which is my code is throwing all errors. Please let me know if I am not clear. My original code is what would seem ideal however there are issues with the way the browser is treating end script tags. – Jack Feb 12 '14 at 13:55
  • Why don't you run js1.js on domready then?? – Milind Anantwar Feb 12 '14 at 13:58
  • that would result in too many changes in all of my files. I am looking for something like my original solution but the string is actually the script tag. – Jack Feb 12 '14 at 14:02
  • Yes there will be. That is the reason it is best practice to load the js that needed first in page head. – Milind Anantwar Feb 12 '14 at 14:07
2

Represent </ inside a JavaScript string literal as <\/.

Escaping the / keeps the meaning the same for the JavaScript parser but not for the HTML parser.

Since you have HTML containing JavaScript containing HTML containing JavaScript containing HTML (!!!) you have to double escape the inner most ones.

I think this will work:

document.write('<script type="text/javascript">window.jQuery || document.write(\"<script src=\'http://code.jquery.com/jquery-1.10.2.min.js\'><\\/script>\")<\/script>');

… but it is horrible and there seems to be little point in generating a new script element just to decide if you want to generate a new script element though. You would get the same result with:

if (!window.jQuery) {
  document.write("<script src='http://code.jquery.com/jquery-1.10.2.min.js'><\/script>";
}
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • I already tried that. It still doesn't work. – Jack Feb 12 '14 at 13:46
  • I didn't realise you needed to escape `/`s in _JavaScript_. `'\/' === '/'; // true` – Paul S. Feb 12 '14 at 13:47
  • 2
    @PaulS. — As I explained, in JavaScript `""` and `"<\/script>"` are equivalent. In HTML, they are different. – Quentin Feb 12 '14 at 13:48
  • @Jack — Oh damn, it's the nesting… I'll update the answer. – Quentin Feb 12 '14 at 13:48
  • @Quentin: Thanks but it still doesn't work. You can try for yourself. :( – Jack Feb 12 '14 at 13:53
  • @Quentin Oh I see now - the `` in the _String_ is actually closing the `` as the close tag and keeps going until the real ``. – Paul S. Feb 12 '14 at 13:57
  • The final version which worked document.write(' – Jack Feb 12 '14 at 14:23
1

It is a good approach to always use CDN but sometimes what if the CDN is down (rare possibility though) but you never know in this world as anything can happen.

Below given jQuery code checks whether jQuery is loaded from Google CDN or not, if not then it references the jQuery.js file from your folder.

<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
<script type="text/javascript">
if (typeof jQuery == 'undefined') 
{
document.write(unescape("%3Cscript src='Scripts/jquery.1.9.1.min.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>

It first loads the jQuery from Google CDN and then check the jQuery object. If jQuery is not loaded successfully then it will references the jQuery.js file from hard drive location. In this example, the jQuery.js is loaded from Scripts folder.

Rahul Kumar
  • 528
  • 1
  • 3
  • 19
1

Break your String down starting from it's innermost nesting, and each time consider where it will be interpreted and therefore how it needs to be encoded.

<script src='http://code.jquery.com/jquery-1.10.2.min.js'></script>

This HTML will be inside a String, escape quotes and backslashes and go up a level in nesting

window.jQuery || document.write("<script src=\'http://code.jquery.com/jquery-1.10.2.min.js\'></script>");

This script will be inside HTML, escape tags and go up a level in nesting

<script type="text/javascript">window.jQuery || document.write("<"+"script src=\'http://code.jquery.com/jquery-1.10.2.min.js\'><"+"/script>");</script>

This HTML will be inside a String, escape quotes and backslashes and go up a level in nesting

document.write('<script type=\"text/javascript\">window.jQuery || document.write(\"<\"+\"script src=\\\'http://code.jquery.com/jquery-1.10.2.min.js\\\'><\"+\"/script>\");</script>');

This will be loaded as an external script so we're done.

I chose to break tags using a "<"+"tag>..<"+"/tag>" style because I find it easier to escape.

Paul S.
  • 64,864
  • 9
  • 122
  • 138