Writing a jquery plugin in coffeescript - how to g

2019-01-21 22:00发布

问题:

I am writing a jquery plugin in coffeescript but am not sure how to get the function wrapper part right.

My coffeescript starts with this:

$.fn.extend({
    myplugin: ->
        @each ->

Which creates the javascript with a function wrapper:

(function() {
  $.fn.extend({
      myplugin: function() {
          return this.each(function() {

but I want a '$' passed in like this:

(function($) {
  $.fn.extend({

Similar for the ending I have... nothing in particular in coffeescript.
I get this in javascript:

})();

But would like this:

})(jQuery);

Does anyone know how to achieve this with the coffeescript compiler? Or what is the best way to get this done within coffeescript?

回答1:

The answer is that you don't need to call it like that in CoffeeScript -- your script is already safely wrapped in a closure, so there's no need for jQuery-passed-in-as-a-parameter-tricks. Just write:

$ = jQuery

... at the top of your script, and you're good to go.



回答2:

Unless you're using the --bare flag in the compiler, the

$ = jQuery

solution is best. If you are, then with the new do keyword, you can write

do ($ = jQuery) ->
   # plugin code...

thus creating the desired scope while avoiding a mess o' parentheses.



回答3:

UPDATE/EDIT: Yep, as per Jeremy's explanation:

$ = jQuery

$.fn.myPlugin = () ->
  console.log('test fired')

compiles to:

(function() {
  var $;
  $ = jQuery;
  $.fn.myPlugin = function() {
    return console.log('test fired');
  };
}).call(this);

Which works just fine as a jQuery plugin: $('body').myPlugin();

Original:

Okay, i think I may getting close on this one, let me know if it helps.

(($) ->
  $.fn.extend =
    myplugin: ->
    @each: ->
)(jQuery)

renders into:

(function() {
  (function($) {
    return $.fn.extend = {
      myplugin: function() {},
      this.each: function() {}
    };
  })(jQuery);
}).call(this);


回答4:

The easiest way is to extend $.fn object

Simple jQuery plugin can be written in CoffeeScript as follows:

$.extend $.fn,

  disable: ->
    @each ->
      e = $(this)
      e.attr("disabled", "disabled") if e.is("button") or e.is("input")

it will compile to

(function() {
  $.extend($.fn, {
    disable: function() {
      return this.each(function() {
        var e;
        e = $(this);
        if (e.is("button") || e.is("input")) {
          return e.attr("disabled", "disabled");
        }
      });
    }
  });
}).call(this);


回答5:

You should take a look at the CoffeeScript version of jQuery Boilerplate ~ https://github.com/zenorocha/jquery-boilerplate/blob/master/jquery.boilerplate.coffee



回答6:

Although this post is old I found it useful. Here is the coffee-script code that works for me.

$ -> 
    $('.my-class').hello()

$.fn.hello=-> 
    @each -> 
        $(@).append $ '<div>Hello</div>'

Note: You don't need to declare the $ variable, you can just use it right out of the box.



回答7:

You could simply add the closure yourself and compile it with the --bare flag.

coffee -w -c --bare jquery.plugin.coffee

(($) ->
  # some code here
)(jQuery)


回答8:

Simple and Straightforward

This is all I had to do in order to add my own method, cleanFadeIn, on jQuery objects. It returns the objects for chaining as well:

$.fn.extend
  cleanFadeIn: ->                     # $('.notice').cleanFadeIn
    return $(@).each ->               # returns the objects for easy chaining.
      $(@).slideDown 'slow', ->
        $(@).fadeTo 'slow', 1