views:

80

answers:

2

So I'm working on a site, and we need to check if jQuery is defined before writing it to the page. I want to convert it to use JS conditional shorthand, but for some reason when I do that the statement does not execute. Here is my code:

Original (this works, tested):

if (typeof jQuery == 'undefined') {
    document.write('<script type="text/javascript" src="', JSPATH_REL_symc + 'jquery-1.4.2.min.js','"><\/script>');
}

That version works perfectly. Now I replaced it with this, and for some reason I'm having issues:

New w/Shorthand:

(typeof jQuery == 'undefined') ? document.write('<script type="text/javascript" src="', JSPATH_REL_symc + 'jquery-1.4.2.min.js','"><\/script>') : '';

Any idea what is wrong with this syntax?

Thanks.

+2  A: 

Nothing appears to be wrong with it at first glance. (The var JSPATH_REL_symc is defined elsewhere, yes?). The code is a little funky (mixing string concatenation and multiple arguments to document.writedocument.write(str, str2 + str3, str4)), but that is easily fixed. Also you ought to be able to simplify (and shorten) the code even further:

this.jQuery || document.write('<script src="'
                              + JSPATH_REL_symc
                              + 'jquery-1.4.2.min.js"><\/script>');

The type attribute of the script tag isn't mandatory, all browsers will implicitly evaluate its contents or the linked file as JavaScript.

A quick test shows this code in action: http://jsfiddle.net/ZWQqM/ (minus the JSPATH argument, and adding in an "onload" event attribute to the script tag to demonstrate that it is successful.)

Ryan Tenney
While the `type` attribute is not mandatory, it is required to pass HTML4/5 compatibility.
Topher Fangio
@Topher: Right on man.@Ryan: This code works great, although of course I will be including the type attr still :) See my response below re: multiple params.
bryan.taylor
+1  A: 

Your code looks a little wonky since you're not actually doing anything in the second part of the conditional and this is probably causing a syntax error.

Basically, when the condition is false, I think it's evaluating to:

'';

which isn't valid. Usually, you would use it like this:

var someString = (someTest == true) ? "Great" : "Bad";
document.write(someString);

Since you're using document.write inside of the conditional; I think you have two options:

  1. Move the conditional inside of the document.write, or
  2. Remove the quotations marks from the second portion of the conditional

Try this:

// Option 1
document.write((typeof jQuery == 'undefined') ? '<script type="text/javascript" src="', JSPATH_REL_symc + 'jquery-1.4.2.min.js','"><\/script>' : '');


// Option 2 -- EDIT: This apparently isn't valid syntax due to the : ; at the end. Thanks @LarsH
(typeof jQuery == 'undefined') ? document.write('<script type="text/javascript" src="', JSPATH_REL_symc + 'jquery-1.4.2.min.js','"><\/script>') : ;

Personally, I think the if statement is clearer though.

EDIT: As stated by Ryan in the comment below, ''; is valid, so I'm not quite sure why that particular code is throwing an error. Can you give a screenshot or description of the error?

Topher Fangio
Actually, `'';` is a valid statement. http://jsfiddle.net/RGPyr/JavaScript Strict mode is enabled by the following statement:`"use strict";`
Ryan Tenney
+1: Using a ternary to save a few bytes on if/else is usually considered ugly and not the easiest to follow. Our company standards disallow it. That's not to say we don't use it, we do when the result of the expression is going to be used (it's ignored in the asker's example). Topher's suggestion uses a ternary more properly, though it may endup with a not very elegant call to document.write("");BTW, I didn't know you could pass multiple parameters to document.write and they would be concatenated. You shouldn't mix concatenation with multiple parameters though.
Juan Mendes
+1 @Ryan Tenney - Thanks for the link. I didn't realize it was valid. Updating my answer accordingly.
Topher Fangio
@Topher - can you update your answer to eliminate Option 2? The ternary conditional with nothing after the `:` is a syntax error.
LarsH
@Juan Mendes: I'm aware of the proper way to write this syntax, but I'm working within the confines of an application that dictates what I can/can't do.As for the doc.write multiple params, that's the only way to pass dynamic URL params to a script include and have it appear properly on the page. Otherwise the browser can have problems interpreting the '/' and the '<script>'. Probably a good idea to do research/ask before advocating the 'proper' or 'best' approach :)And I think the view that ternary ops are ugly is a naive coding view, they're very easy to read if you have previous exp.
bryan.taylor
@bryan.taylor I agree it's not that complicated, but out of all the places I've coded at, developers never liked it and agreed that ternaries should only be used when you're making use of the expression's return value. Also, I find it hard to believe that mixing string concatenation with a list of strings fixes the closing script tag problem. AFAIK, all you have to do is make sure you break up the closing script tag into two strings like: document.write("<script src='"+SCRIPT_SRC+"'>"+"</"+"script>"); or document.write("<script src='",SCRIPT_SRC,"'>","</","script>").
Juan Mendes
@Juan Mendes:Like I said, it's mainly due to the path issue. What you posted just now is essentially exactly what I did, except I mixed one string concat with one additional argument. I tried many methods for the document.write() breakup, including the first of your examples, but for some reason the syntax I posted above is the only one that worked reliably. Damn you, proprietary software! ::shakes fist::
bryan.taylor
@LarsH - Updated the code comment to mention that it's not valid. I figured since my answer wasn't the accepted one, and those options were more used as examples, I would leave it be.
Topher Fangio