问题
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?
回答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:
- https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Logical_Operators
回答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");
};
来源:https://stackoverflow.com/questions/16500728/conditionally-load-javascript-resource