Authoring a Plugin ($.fn)

Extend jQuery with your own reusable, chainable method by adding to $.fn.

Every jQuery method you already love — .hide(), .addClass(), .on() — lives on $.fn, the prototype shared by every jQuery object. When you want a piece of behaviour you can reuse across a project, you write your own method the exact same way the library does.

The three habits of a well-behaved plugin

  • Return this so callers can keep chaining.
  • Iterate the set with this.each() — a selector can match many elements.
  • Wrap in an IIFE that receives jQuery as $, so your code is safe even on noConflict pages.

Here is the smallest plugin worth writing — it highlights each matched element:

(function ($) {
  $.fn.highlight = function (color) {
    return this.each(function () {
      $(this).css("background", color || "#ffe58a");
    });
  };
})(jQuery);

$("p").highlight();          // works on every <p>
$("h1").highlight("#5BA3D0").addClass("done"); // still chainable

Accepting options the jQuery way

Real plugins take an options object and merge it over sensible defaults with $.extend, so callers override only what they care about:

$.fn.badge = function (opts) {
  var o = $.extend({ text: "NEW", bg: "#0769AD" }, opts);
  return this.each(function () {
    $(this).append($("<span>").text(o.text).css("background", o.bg));
  });
};

That $.extend({}, defaults, opts) pattern is the beating heart of nearly every jQuery plugin ever shipped.

Example

Try it yourself
Loading editor…
Press Run to see the result.

When to use it

  • A UI library ships a .tooltip() plugin so developers can activate tooltips with a single $('.tip').tooltip() call.
  • A form team packages shared validation as a $.fn.validate plugin, keeping reuse DRY across multiple page scripts.
  • A charting toolkit adds a $.fn.sparkline plugin so any inline <span> can render a mini chart without extra markup.

More examples

Minimal chainable plugin

Returning this from the plugin function preserves the jQuery object so callers can continue chaining methods.

Example Β· html
(function ($) {
  $.fn.highlight = function (color) {
    color = color || "yellow";
    return this.css("background", color);
  };
}(jQuery));

$(function () {
  $("p.note").highlight("#b3f5b3").addClass("highlighted");
});

Plugin with default options

$.extend() merges caller-supplied options over the defaults so all options are optional with sensible fallbacks.

Example Β· html
(function ($) {
  $.fn.badge = function (options) {
    var opts = $.extend({ text: "New", color: "#e74c3c" }, options);
    return this.each(function () {
      var $badge = $("<span>")
        .text(opts.text)
        .css({ background: opts.color, color: "#fff",
               padding: "2px 6px", borderRadius: "10px" });
      $(this).append($badge);
    });
  };
}(jQuery));

$(function () {
  $(".item").badge({ text: "Hot", color: "#e67e22" });
});

Plugin with per-element state via data()

Storing state in .data() keeps each element's toggle state independent when the plugin is applied to many elements.

Example Β· html
(function ($) {
  $.fn.toggler = function () {
    return this.each(function () {
      var $el = $(this);
      var open = $el.data("toggler-open") || false;
      $el.on("click.toggler", function () {
        open = !open;
        $el.data("toggler-open", open)
           .text(open ? "Close" : "Open");
      });
    });
  };
}(jQuery));

$(function () { $(".panel-toggle").toggler(); });

Discussion

  • Be the first to comment on this lesson.