Reputation: 86230
On How to Create a Basic Plugin there is a section titled Protecting the $ Alias and Adding Scope.
The $ variable is very popular among JavaScript libraries, and if you're using another library with jQuery, you will have to make jQuery not use the $ with jQuery.noConflict(). However, this will break our plugin since it is written with the assumption that $ is an alias to the jQuery function. To work well with other plugins, and still use the jQuery $ alias, we need to put all of our code inside of an Immediately Invoked Function Expression, and then pass the function jQuery, and name the parameter $:
In JavaScript, this wrapper looks like this:
(function ( $ ) {
// do stuff
return this;
})(jQuery)
How can this be translated into CoffeeScript?
Upvotes: 1
Views: 105
Reputation: 231385
This coffeescript:
$ = jQuery
### do stuff ###
compiles to:
// Generated by CoffeeScript 1.6.3
(function() {
var $;
$ = jQuery;
/* do stuff*/
}).call(this);
I think the effect is the same, ensuring that $
points to jQuery
regardless of what $
is in the calling environment.
This is what the author of Coffeescript recommends in Writing a jquery plugin in coffeescript - how to get "(function($)" and "(jQuery)"?
To get closer to the original pattern (do
is still something of a blackbox to me)
do ($=jQuery) ->
### do stuff ###
@
'bare' compiles to:
// Generated by CoffeeScript 1.6.3
(function($) {
/* do stuff*/
return this;
})(jQuery);
Upvotes: 2
Reputation: 86230
At first it's non-obvious. Here's the skeleton.
$.fn.ourFunction = do ($=jQuery) -> (opts) ->
# do stuff
@
It compiles to this:
$.fn.ourFunction = (function($) {
return function(opts) {
return this;
};
})(jQuery);
We could also split this into several lines for clarity.
$.fn.ourFunction = do ($=jQuery) ->
(opts) ->
# do stuff
@
Our first line uses the do
syntax, which runs a function initially. We can also specify parameters (e.g. $
), and their values (e.g. jQuery
).
$.fn.ourFunction = do ($=jQuery) ->
Our second line creates a function, which is returned. Remember, everything in CoffeeScript is an expression, so we don't need to say return (opts) ->
(but you can).
(opts) ->
Then, there's of course the body of our code, where the actual work happens. One trick that I left out of the initial code is to use the =>
operator to maintain scope. Inside our scroll handler, we can force this
to remain our targeted object. We could call $('#something').ourFunction()
and we effectively call $('#something').something()
in our scroll handler.
$.fn.ourFunction = do ($=jQuery) ->
(opts) ->
$(window).scroll =>
this.something()
@something()
@
Our last line is simply the @
character. This allows chaining, because we're returning this
. Alternatively, if our last line calls another chainable method on this
, we don't need to make it explicit.
$.fn.flash = do ($=jQuery) -> (opts) ->
@animate(opacity: 0).delay()
.animate({opacity: 1})
Upvotes: 1