<html>
<head>
<script class="jsbin" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
article, aside, figure, footer, header, hgroup,
menu, nav, section { display: block; }
body { font-family: 'Georgia'; font-size:1.2em; padding:20px; text-shadow: 0 2px 0 rgba(255, 255, 255, 0.35); background: #eee; color:#000;}
h1, h2, h3 { margin-bottom: 1.3em; color:#000; text-shadow: 0 2px 0 rgba(255, 255, 255, 0.35); font-weight:bold; }
h1 { font-size:2.5em; }
h2 { font-size:1.7em; }
h3 { font-size:1.4em; margin-top:0; }
ul { list-style: 'disc'; }
ul li { margin-bottom: 0.5em; line-height:1.5em; }
.slide { margin:0 auto; position:relative;}
.slide a { color:#66a;}
.code { font-family: 'Lucida Console'; color:#3b3; }
ul li.cont { list-style:none; color:#444; padding-left:0.5em;}
ul li.intro { list-style:none; color:#000; margin-left:-2em;}
button.prev { position:absolute; bottom:100px; left:-30px; border:2px solid #444; border-left:0; background:#999; cursor:pointer; }
</style>
</head>
<body>
<div class="slide">
<h1>
Introduction to jQuery Plugin Development
</h1>
<h3>
by Alistair Macdonald
</h3>
</div>
<div class="slide">
<h2>
What does it mean to have a plugin?
</h2>
<ul>
<li class="intro">
It usually means we have a package of self-contained code that:
</li>
<li>
extends the core functionality of whatever we are plugging it into
</li>
<li>
we can re-use in many projects
</li>
<li>
we can configure and/or extend, without needing to edit the plugin source code, on a project by project basis
</li>
<li>
we can use beside other plugins and code libraries without conflict
</li>
<li>
can be shared
</li>
</ul>
</div>
<div class="slide">
<h2>
What's so good about jQuery plugins?
</h2>
<ul>
<li class="intro">
jQuery of course!
</li>
<li>
jQuery is widely available, well supported and most likely cached
</li>
<li>
jQuery plugins can maintain jQuery chainability
</li>
<li>
large community
</li>
</ul>
</div>
<div class="slide">
<h2>
What are some practical examples?
</h2>
<ul>
<li>
<a href="http://jquery.malsup.com/cycle/begin.html">
Mike Alsup's cycle
</a>
</li>
<li>
<a href="https://github.com/jquery/jquery-metadata/blob/master/jquery.metadata.js">
metadata
</a>
this plugin pattern allows global settings to be made for all collection methods
</li>
<li>
this slideshow is created with a
<a href="http://jsbin.com/ayakox/9/edit">
plugin
</a>
this plugin pattern follows the <a href="http://docs.jquery.com/Plugins/Authoring">official jQuery example</a>
</li>
</ul>
</div>
<div class="slide">
<h2>
How do we create a plugin?
</h2>
<ul>
<li class="intro">
for our code to become a jQuery plugin we need to extend the core functionality of jQuery. We can do this by:
</li>
<li>
adding a function to the top level jQuery object:
</li>
<li class="cont">
<span class="code">
$.foo = function(){ ... };
</span>
</li>
<li class="cont">
we can invoke the utility function thus
<span class="code">
$.foo();
</span>
</li>
<li>
or create a new method on the jQuery.fn object:
</li>
<li class="cont">
<span class="code">
$.fn.foo = function(){ ... };
</span>
</li>
<li class="cont">
which we can invoke with
<span class="code">
$('div.bar').foo();
</span>
and where the
<span class="code">
this
</span>
inside the function will be the result of
<span class="code">
$('div.bar')
</span>
which is a jQuery collection
</li>
<li>
<a href="http://jsbin.com/ovozef/2/edit">
let's make a plugin now...
</a>
</li>
</ul>
</div>
<div class="slide">
<h2>
What should we bear in mind?
</h2>
<ul>
<li>
avoid namespace collisions and keep the code private by wrapping your code within a closure:
</li>
<li class="cont">
<span class="code">
(function($){ ...//plugin code//... })(jQuery);
</span>
</li>
<li>
the
<span class="code">
this
</span>
in $.fn functions (jQuery collection methods) is a jQuery object already and does not need to wrapped like
<span class="code">
$(this)
</span>
</li>
<li>
we can use the <a href="http://api.jquery.com/jQuery.extend/">$.extend() function</a> to merge passed objects with default objects
</li>
<li>
are there any dependencies (versions and other plugins/libraries)?
</li>
<li>
include good comments
</li>
</ul>
</div>
<div class="slide">
<h2>
Should I share?
</h2>
<ul>
<li>
if you legally can
</li>
<li>
if you want to solicit improvements from the community
</li>
<li>
if you want to make a better world!
</li>
</ul>
</div>
<div class="slide">
<h2>
When not to create a plugin?
</h2>
<ul>
<li>
when one exists already
</li>
<li>
when it creates more work than it saves
</li>
<li>
when the use-case is too specific
</li>
</ul>
</div>
</body>
</html>
(function($) {
$.fn.clickthrough = function(options) {
//private vars
var number_of_slides = this.length,
slides = this,
settings = $.extend({
'control_lis': true,
'slide_width': '600px',
'slide_height': '550px',
'back_button': true
}, options);
return this.each(function(i, slide) {
//hide all slides except the first one
if (i > 0)
$(this).hide();
//private vars per slide
var next_slide = (i + 1 < number_of_slides) ? i + 1 : 0,
prev_slide = (i - 1 > 0) ? i - 1 : 0,
$lis = (settings.control_lis) ? $(this).find('li').hide() : [],
li_tracker = 0,
$this_slide = $(slide);
//wrap the slide content into a central box to suit our
//resolution and make the clickable slide full width and height
$(this)
.wrapInner('<div class="slide-content" />')
.css('width', '100%')
.css('min-height', window.innerHeight + 'px');
$('div.slide-content')
.css('width', settings.slide_width)
.css('min-height', settings.slide_height)
.css('margin', '0 auto');
//append a back button if requested by the settings
if (settings.back_button && next_slide > 1) {
$this_slide.append('<button name="prev" class="prev"><</button>')
.find('button.prev')
.bind('click.prev', function(e) {
e.stopPropagation();
$(this).parent().fadeOut('slow', function() {
if (settings.control_lis) {
li_tracker = 0;
$lis.hide();
}
$(slides.eq(prev_slide)).fadeIn();
});
});
}
$(this).bind('click.clickthrough', function() {
if (settings.control_lis && li_tracker < $lis.length) {
$lis.eq(li_tracker).fadeIn();
li_tracker++;
} else {
$(this).fadeOut('slow', function() {
//only worry about lis if we are controlling them
if (settings.control_lis) {
li_tracker = 0;
$lis.hide();
}
$(slides[next_slide]).fadeIn();
});
}
});
//stop all hyperlink clicks from propagating through to parent
$(this)
.find("a")
.attr("target","_blank")
.bind('click', function(e){
e.stopPropagation();
});
});
};
})(jQuery);
$(document).ready(function() {
$('div.slide').clickthrough({
'slide_width': '600px',
'control_lis': true
});
});
Output
300px
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |