2

I'm creating a website which some of it's pages contain at least one media player and because of the page size limitations, I want to load the media player javascript file only in pages that have medias. I store media information in an javascript object in head of the page and other script files are being loaded at the end of body.

I found this solution (using $.getScript) very nice but I want a solution that doesn't rely on any frameworks. I saw an interesting implementation in jQuery website and I changed it like this:

<script>typeof(player) != 'object' || document.write(unescape('%3Cscript src="/assets/js/player/mediaplayer/jwplayer.js"%3E%3C/script%3E'));</script>

and it works like a charm but as I'm not pro in javascript I want to know how does this work?

  • If we don't have a variable with type of object there is no need to check the second condition?
  • How other browsers act on this code?
  • Do all of them (even older IEs) skip the second condition or they may check all the conditions?
  • Is there any better solution with cross-browser behavior?
Community
  • 1
  • 1
Farid Rn
  • 3,167
  • 5
  • 39
  • 66
  • There's no way you can do this on the server? Would seem a lot easier. – mccannf May 11 '13 at 19:08
  • @mccannf check the js object with php? parse html output to load a js file? are you sure it's faster? – Farid Rn May 11 '13 at 19:10
  • 1
    no parsing required if the html is being generated by php in the first place. it can just include the required ` – Mark Reed May 11 '13 at 19:11
  • As @MarkReed says, use PHP to conditionally include scripts based on what is being served up in the page. – mccannf May 11 '13 at 19:16
  • @MarkReed I'm using Joomla and player object is being generated in a system plugin and I'm generating the player script code at the bottom of page in my template. – Farid Rn May 11 '13 at 20:11

2 Answers2

2

Use a more standard approach to loading:

jQuery

Use getScript

if (typeof player != "object") {
    $.getScript("/assets/js/player/mediaplayer/jwplayer.js");
};

Raw JavaScript

function loadScript(path) {
    var script = document.createElement("script");
    script.src = path;
    script.type = "text/javascript";
    // changed "target" to "head"
    var head = document.getElementsByTagName("head")[0];
    head.appendChild(script);
};

Then in your code:

if (typeof player != 'object') {
    loadScript("/assets/js/player/mediaplayer/jwplayer.js");
};
flavian
  • 28,161
  • 11
  • 65
  • 105
  • `this solution` in my question refer to getScript and as I described, that I may want to load the js file before loading jQuery and I want a not-using-any-framework solution. Anyhow your raw js solutions seems interesting, +1 for that. – Farid Rn May 11 '13 at 20:15
  • @commadelimited Someone updated the post for reasons unknown. – flavian Feb 19 '14 at 23:07
  • I'm the one who updated the post. I realized I should have just done that rather than leaving a comment. – commadelimited Feb 20 '14 at 18:30
1

What you're referring to is called short circuiting.

The code you see uses ||, which is the "or" operator. So for an "or" operator, only one of the operands needs to be true. That means that as soon as one of the operands fulfills the condition, the rest aren't evaluated. For example:

if (returnTrue() || returnFalse()) {

(where the functions speak for themselves) the returnFalse() method won't even be called because of short circuiting. The returnTrue() condition fulfills the "or" operator, because one of the operands (the first) evaluates to true.

An "and" operator is the opposite, where all of the operands must evaluate to true in order for it to be fulfilled.

For example:

if (returnTrue() && returnFalse()) {

The returnFalse() will be called because the if statement needs to know if all operands evaluate to true. Since the first one is true, it continues evaluating the operands. Another example:

if (returnTrue() && returnFalse() && returnTrue()) {

Only the first two calls will execute, but returnFalse() ruins the comparison, and it short circuits before it can get to the last returnTrue()

All of these "rules" apply to outside of an if statement, which is why your code works. So with your code, it's saying "if player is an object, continue evaluating operands." Your code is basically the same as:

if (typeof(player) == 'object') {
    document.write("stuff");
}

which I'm sure you know.

Reference:

Ian
  • 50,146
  • 13
  • 101
  • 111
  • The reason I said I want a cross-browser solution is that because I found [this page](http://unixpapa.com/js/dyna.html) about **Dynamic Script Loading** but in the middle of the article there's an example about IE and it says *... `this.readyState == 'loaded' || this.readyState == 'complete'`, but that risks triggering twice* and that worried me about behaviour of *short circuit conditions* in Internet Explorer, specially in older version which are slow enough and loading more external resources may make it even slower. – Farid Rn May 11 '13 at 20:43