I grabbed this code form JCarousel and just trying to understand these lines below. I\'m new to jQuery and not that great at JavaScript so I am not sure what is jQuery and
Ok guys, I'd like to bring my share to this topic, and tell you about the easiest way to disable clicked dialog button. Here goes:
$("#dialog-selector").dialog({ title: "Dialog", // Other options buttons: { "Ок": function(e) { $(e.currentTarget).attr("disabled", true); } } });
[n ? 'bind' : 'unbind']
Is an if statement, which can be rewritten as
if (n) // if n is true
{
'bind';
}
else
{
'unbind';
}
So if n is true, it would evaluate like this
this.buttonNext.bind((this.options.buttonNextEvent, this.funcNext))
because [ ] notation is the same as . notation.
buttonNext[bind] is the same as buttonNext.bind
To summarize what you posted, it checks the states of variables (n and p) which holds the state of the button. If it is enabled, then when activated it disables it, adds the disabled classes, etc. If it's disabled, it sets it to enabled and removes the disabled class.
The first part to understand is symbol resolution. Javacript supports both dot-notation and bracket-notation.
Consider opening a new window.
window.open()
This is dot-notation in action. you're telling the interpreter that "open" can be found on "window". But there's another way to do this
window['open']()
Same thing, but with bracket notation. Instead of using the symbol name directly, we're using a string literal instead. What this means is that by using bracket-notation for symbol resolution, we can do it in a dynamic way, since we can choose or build strings on the fly, which is exactly what this snippet does.
this.buttonNext[n ? 'bind' : 'unbind'](...);
Is analagous to
if ( n )
{
this.buttonNext.bind(...);
} else {
this.buttonNext.unbind(...);
}
If you don't recognize the ?: syntax, that's the conditional operator, or conditional expression
[expression] ? [valueIfTrue] : [valueIfFalse]
This is extremely often erroneously called the "ternary operator", when in fact it just a ternary operator (an operator with three operands). The reason for this is because in javascript (and most languages) is the only ternary operator, so that description usually flies.
Does that help? is there anything else you need cleared up?
IMHO, that code is completely unreadable as you would agree.
As Peter wrote, you need to know that JavaScript method could be called using DOT notation or BRACKET notation.
Also, jQuery supports chaining.
Once you know these two things, here's how the code break downs.
this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
The above line does three things. Binds/Unbinds event, add/removes class and enables/disables the 'buttonNext'.
Bind/unbind step
this.buttonNext[n ? 'bind' :'unbind']
(this.options.buttonNextEvent, this.funcNext);
You are calling the 'bind'
or 'unbind'
depending upon whether n
is true
or false
. More importantly, the bind
method call will return this.buttonNext
.
addClass/removeClass step
this.buttonNext[n ? 'removeClass' : 'addClass']
(this.className('jcarousel-next-disabled'))
Again, based on n
, it will either call the addClass
or the removeClass
method passing it the appropriate class name. You get the same this.buttonNext
object back.
Finally, enable/disable button step
this.buttonNext.attr('disabled', n ? false : true);
Disabling/enabling the button based on whether n
is true
or false
.
Even though I love chaining, I think chaining was misused in this code.
These two lines check if there are any "next" or "prev" items to display and enables/disables the buttons accordingly by adding disabled jcarousel-next-disabled(enabled) and setting the disabled attr to true/false.
These lines are in the middle of a method that takes two parameters.
n // whether to show the next button
p // whether to show the previous button
Either of these buttons can be null or undefined, which causes jCarousel to look at other factors, like whether or not the carousel is locked.
Take a look at this:
lock: function() {
this.locked = true;
this.buttons();
},
unlock: function() {
this.locked = false;
this.buttons();
}
If you look a few lines up from your two lines, you'll see that this.locked is taken into consideration for setting n and p when they are not passed in as true.
Let's break apart one of the lines a bit:
this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
bindMethod = n ? "bind" : "unbind"; // bind if n is true; otherwise unbind
this.options.buttonNextEvent // defaults to "click", can be changed in the options
this.funcNext // function() { self.next(); }; // self is a local available to the closure
changeClass = n ? "removeClass" : "addClass" // same as above
this.className("jcarousel-next-disabled") // adds -vertical or -horizontal to the class
toDisable = !n // Effectively
So, one way this might work would be:
this.buttonNext.bind("click", function() { self.next(); }).removeClass("jcarousel-next-disabled-horizontal").attr("disabled", false);
And as other pointed out, JavaScript supports both bracket and symbol notation. The following two are identical:
x.y
x["y"]
Note that bracket notation is a bit more flexible:
x.omg-omg // Illegal
x["omg-omg"] // Legal
Also note that methods are just property lookup plus invocation. The following two are identical:
x.omg()
x["omg"]()
Which means you can also do this:
x[someVariable]()
Tada! Hope that helped.