-2

Basically I have a script.js in my website that does this:

if (someVar){
   document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>');
}

Now I would like to attack some behaviour:

if (someVar){
   document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>');

  $(document).ready(function(){
     //> Do stuff
  });
}

But I got undeclared function $ in console

Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989
  • otherwise browser stop reading the script.js –  Mar 10 '12 at 16:13
  • Didn't you surround your `script` block with `CDATA` or an HTML comment? You'd best be careful of *everything* that looks like an HTML entity, then... – Lightness Races in Orbit Mar 10 '12 at 16:14
  • @DOK: Escaping it from what? Slashes aren't special characters. – Lightness Races in Orbit Mar 10 '12 at 16:14
  • CDATA is for XML, I am using HTML 5 therefor no need for cdata and all other pretty bad looking code like that. Regards escape, i am not escpaing / it's just the simple way to don't have a clearly ` ` in documetn write otherwise browers stop reading there –  Mar 10 '12 at 16:17
  • Why not an HTML comment? `` – Lightness Races in Orbit Mar 10 '12 at 16:23
  • The comment block also prevents your Javascript from being interpreted as HTML, so that you don't need to intersperse your code with things that mangle it, like injecting backslashes into parts of what would otherwise be nice, clear, legible, verbatim HTML in strings. And citing Google's HTML as an example of good code is utterly ludicrous. And I don't see the relevance of what year number we happen to be on. – Lightness Races in Orbit Mar 10 '12 at 16:26
  • That logic doesn't make any sense. **Basis:** HTML-commenting scripts both hide scripts from older browsers, and avoid the requirement to clean it in _all_ browsers. **Advance:** We don't need to hide scripts from older browsers any more. **Your conclusion:** We should not HTML-comment scripts, and we should messily mangle our code with backslashes instead. **Me:** huh?!?!?!? – Lightness Races in Orbit Mar 10 '12 at 16:35
  • And you're welcome to use programming techniques just because jQuery.com uses them, but I'd encourage you to instead apply some of your _own_ thought and intellect rather than just blindly following what somebody else is doing. Especially just because they're famous. – Lightness Races in Orbit Mar 10 '12 at 16:36
  • @LightnessRacesinOrbit: just FYI i have deleted our chat, I believe it's not useful for anyone –  Mar 10 '12 at 16:45
  • @LightnessRacesinOrbit The character sequence `` in the body of a script signals to the HTML/XML parser that the script tag is terminating. Same deal with `` in a textarea. The parsers aren't smart enough to realize that `` is inside of a quoted string or whatever. So, you have to do stuff like `"" + "script>"` if your script is going in an HTML document rather than an external .js file. CDATA sections work around that nicely for XML parsers... HTML parsers don't need to honor CDATA sections. http://en.wikipedia.org/wiki/CDATA#Use_of_CDATA_in_program_output – Dagg Nabbit Mar 11 '12 at 01:10
  • @GGG: And comment sections don't fix that? – Lightness Races in Orbit Mar 11 '12 at 03:04
  • @LightnessRacesinOrbit I don't see why they wouldn't, but do you really want to write `/* */`? HTML parsers don't have a problem with ` – Dagg Nabbit Mar 11 '12 at 03:11
  • @GGG: I do, and it's not. It's far preferable to having to mangle the script itself. – Lightness Races in Orbit Mar 11 '12 at 10:33
  • @LightnessRacesinOrbit how many times does the text "" actually appear in your scripts? That should be the *only* thing you need to escape for HTML support. If you've got more than one "" in a script, it's probably a big enough script to move into its own .js file (or needs to be refactored). Sticking a single backslash in a string is a lot less "mangling" than js-commenting some html comments, IMO... that's just ugly. w3schools-ism: http://www.w3schools.com/tags/tag_comment.asp – Dagg Nabbit Mar 11 '12 at 20:10
  • @GGG: I want to have to escape _zero_ things, not just in this specific script, but _ever_. And pretending that a w3schools link is some kind of logical evidence against my suggestion is... baseless. – Lightness Races in Orbit Mar 11 '12 at 21:05
  • @LightnessRacesinOrbit out of curiosity, do you *always* add the HTML comment inside of the script, in case you might need to have `` in a string literal, or do you just add it later as needed? The first case seems unnecessary. Also does your text editor's syntax highlighting not break on ``? Mine does... – Dagg Nabbit Mar 11 '12 at 21:08
  • About the w3schools thing, you're right, just because they are often wildly inaccurate doesn't mean something they said is necessarily wrong. I wonder, though, if any reliable source is suggesting to put HTML comments in script tags, for any reason other than not to confuse really, really old browsers? I especially wonder if there is any reliable reference claiming that HTML comments are the proper way to escape `` inside of a script. I did a bit of searching but didn't find much. – Dagg Nabbit Mar 11 '12 at 21:22
  • Also, http://www.jibbering.com/faq/faq_notes/script_tags.html#hsETO – Dagg Nabbit Mar 11 '12 at 21:31

4 Answers4

2

document.write writes given string after the script it was called in. If you want to bind to $(document).ready() you can move this part of code to a separate file, that is included after the file with document.write function.

Just_Mad
  • 3,631
  • 3
  • 19
  • 26
1

document.write is not content-aware; that is, if you use it to add a <script> element to a page, it will not wait for the content of that element to be loaded and executed before continuing.

If you would like to dynamically load a JavaScript library with a callback, then I suggest using Request.js or a similar library, which will allow you to accomplish your goals like this:

require(["jquery"], function($) {
    $(function() {
        alert('ready');
    });
});
0

document.write actually overwrites the source of your document. For this reason, you should NEVER use it.

The proper way to attach a script tag is like this:

jqueryScript = document.createElement('script');
jqueryScript.setAttribute('src','http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js');
document.body.appendChild(jqueryScript);
//do your jquery stuff

More reading on why you should never use document.write: Why is document.write considered a "bad practice"?

Community
  • 1
  • 1
Chris Sobolewski
  • 12,363
  • 12
  • 56
  • 95
  • 3
    Your opinion on `document.write` doesn't solve the issue. And it doesn't overwrite the source if called when the page is loading, which is what is being done here. The way you're adding the script, it will be asynchronous, so your "jQuery stuff" will need to be in a callback instead of just being placed after the `appendChild()`. –  Mar 10 '12 at 16:32
  • Just for the record, I'm not stating my opinion on document.write. I'm stating accepted best practice. If you give document.write as any part of any answer at a job interview, expect not to get that job. Unless the question was "What's a javascript method you should never use, unless someone had your grandmother at gunpoint?" – Chris Sobolewski Mar 10 '12 at 17:22
  • Oh goodness. The *"it can be misused/misunderstood, so never use it"* mentality is just silly. There are good uses. Irrespective of one's opinion on `document.write`, your solution still does not resolve the issue. It will present the same issue of `$` being `undefined`. –  Mar 10 '12 at 17:31
  • 1
    @ChrisSobolewski look at the generated source on a Stack Overflow page, and search it for `document.write`. Some page other than this one, obviously. – Dagg Nabbit Mar 11 '12 at 21:10
-1

External script does not block code so jquery is not available immediately. You need to do this:

<script>
if (someVar){
   document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>');
}
</script>
<script>
If  (someVar){
  $(document).ready(function(){
     //> Do stuff
  });
}
</script>
Kernel James
  • 2,830
  • 18
  • 17