jquery plugin development by mike alsup. what is a plugin? why write one? a way to extend the core...
TRANSCRIPT
jQuery Plugin Development
By Mike Alsup
What is a plugin? Why Write One?
• A way to extend the core library
• A way to reuse code• A way to contribute!
Agenda
• Quick Overview of Types• Considerations, Rules, Conventions• Diving In• Tips• Q&A
Types of Plugins
• Methods: Element-centric$(‘#myDiv’).myPlugin();
• Psuedo ExpressionsExtend jQuery.expr[:] object
• AnimationsExtend jQuery.easing or jQuery.fx.speed
Considerations
• Host EnvironmentTarget AudienceOther Libraries installedOlder versions of jQuery
• Documentation• Extensibility / Flexibility• Interoperability
Metadata pluginEasing plugin
“Rules”• jQuery vs $
Don’t use the global ‘$’Use ‘jQuery’ or a closure-protected ‘$’
• Implicit iteration $(‘<div>’).hide();Iterate the nodeset
• Honor Chaining $().one().two()return “this”
• SemicolonsUse ‘em
Conventions
• NamespacesChoose one (ex: $(...).myPlugin() )
• Plugin closure pattern;(function($){ /* my code here! */})(jQuery);
• $this, $that ex: var $this = $(this)
• File namejquery.pluginname.js
The Extension Point
• jQuery.fn• jQuery.fn === jQuery.prototype• jQuery.fn.myPlugin = function() …
Getting Started
// a simple no-op pluginjQuery.fn.myPlugin = function() {
}
Getting Started
// a simple no-op pluginjQuery.fn.myPlugin = function() {
// what is this? return this;};
Honor chaining
Getting Started
// a simple no-op pluginjQuery.fn.myPlugin = function() { this.each(function() { // what is this? }); return this;};
Iterate the nodeset
Honor chaining
Getting Started;(function($) {
// a simple no-op plugin$.fn.myPlugin = function() { this.each(function() { ... }); return this;};
})(jQuery);
$(‘#myDiv’).myPlugin();
Use a closure
Iterate the nodeset
Honor chaining
Example 1
Change the colors of an element when hovering over it.
Example 1<html><head><script type="text/javascript" src="../jquery-1.2.6.js"></script><style type="text/css">
</style></head><body> <div id="sidebar"> <div><h1>Heading One</h1>content ...</div> <div><h1>Heading Two</h1>content ...</div> <div><h1>Heading Three</h1>content ...</div> </div> <div id=“main"> <div><h1>Heading One</h1>content ...</div> <div><h1>Heading Two</h1>content ...</div> <div><h1>Heading Three</h1>content ...</div> </div></body></html>
Example 1<html><head><script type="text/javascript" src="../jquery-1.2.6.js"></script><style type="text/css">.highlight { background-color: #ffd }</style></head><body> <div id="sidebar"> <div><h1>Heading One</h1>content ...</div> <div><h1>Heading Two</h1>content ...</div> <div><h1>Heading Three</h1>content ...</div> </div> <div id=“main"> <div><h1>Heading One</h1>content ...</div> <div><h1>Heading Two</h1>content ...</div> <div><h1>Heading Three</h1>content ...</div> </div></body></html>
Example 1 – cont.<script type="text/javascript">
$(document).ready(function() {
$('h1').hover( function() { $(this).addClass('highlight'); }, function () { $(this).removeClass('highlight'); } );
});
</script>
Example 1 – cont.<script type="text/javascript">
$(document).ready(function() {
$('#main h1').hover( function() { $(this).addClass('highlight'); }, function () { $(this).removeClass('highlight'); } );
$('#sidebar h1').hover( function() { $(this).addClass('highlight2'); }, function () { $(this).removeClass('highlight2'); } );
});</script>
Example 1 – cont.<script type="text/javascript">
</script>
Example 1 – cont.<script type="text/javascript">
;(function($) {
})(jQuery);
$(document).ready(function() {
});
</script>
Example 1 – cont.<script type="text/javascript">
;(function($) {
$.fn.hoverClass = function(c) {
};
})(jQuery);
$(document).ready(function() {
});
</script>
Example 1 – cont.<script type="text/javascript">
;(function($) {
$.fn.hoverClass = function(c) { return this.hover( function() { $(this).addClass(c); }, function () { $(this).removeClass(c); } );};
})(jQuery);
$(document).ready(function() {
});
</script>
...this.hover(function() { ...});return this;
...return this.hover(function() { ...});
Example 1 – cont.<script type="text/javascript">
;(function($) {
$.fn.hoverClass = function(c) { return this.hover( function() { $(this).addClass(c); }, function () { $(this).removeClass(c); } );};
})(jQuery);
$(document).ready(function() { $('#main h1').hoverClass('highlight'); $('#sidebar h1').hoverClass('highlight2');});
</script>
Example 1 - jquery.hoverClass.js
;(function($) {
$.fn.hoverClass = function(c) { return this.hover( function() { $(this).addClass(c); }, function () { $(this).removeClass(c); } );};
})(jQuery);
Example 1 – complete
<html><head><script type="text/javascript" src=“jquery-1.2.6.js"></script><script type="text/javascript" src="jquery.hoverClass.js"></script><script type="text/javascript"><style type=“text/css”> ... </style>
$(document).ready(function() { $('#main h1').hoverClass('highlight'); $('#sidebar h1').hoverClass('highlight2');});
</script></head><body>...
Example 2
Submit a form using AJAX
<form id="form1" action="test.php" method="POST"> Name: <input type="text" name="user" /> Comment: <input type="text" name="comment" /> <input type="submit" value="Submit" /></form>
Example 2
Example 2
<form id="form1" action="test.php" method="POST"> Name: <input type="text" name="user" /> Comment: <input type="text" name="comment" /> <input type="submit" value="Submit" /></form>
;(function($) {
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function() {
};
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function() {
return this.submit(function() {
});};
})(jQuery);
Example 2
...this.submit(function() { ...});return this;
...return this.submit(function() { ...});
;(function($) {
$.fn.formlite = function() {
return this.submit(function() {
var $form = $(this);
});
};
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function() {
return this.submit(function() {
var $form = $(this);
$.ajax({ url: $form.attr(‘action’), type: $form.attr(‘method’) || ‘GET’ data: $form.serialize() });
});
};
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function() {
return this.submit(function() {
var $form = $(this);
$.ajax({ url: $form.attr(‘action’), type: $form.attr(‘method’) || ‘GET’ data: $form.serialize() });
return false;
});
};
})(jQuery);
jquery.formlite.js
<html><head><script type=“text/javascript” src=“jquery.formlite1.js”></script><script type=“text/javascript”>$(document).ready(function() { $('#form1').formlite();});</script></head><body> <form id="form1" action="test.php" method="POST"> Name: <input type="text" name="user" /> Comment: <input type="text" name="comment" /> <input type="submit" value="Submit" /> </form></body></html>
Example 2
Options
;(function($) {
$.fn.formlite = function(options) {
return this.submit(function() {
var $form = $(this);
$.ajax({ url: $form.attr(‘action’), type: $form.attr(‘method’) || ‘GET’ data: $form.serialize() });
return false;
});
};
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function(options) {
return this.submit(function() {
var $form = $(this);
var opts = $.extend({ url: $form.attr('action'), method: $form.attr('method') || ‘GET’ }, options || {});
$.ajax({ url: opts.url, type: opts.method, data: $form.serialize() });
return false;
});
};
})(jQuery);
Example 2
<html><head><script type=“text/javascript” src=“jquery.formlite.js”></script><script type=“text/javascript”>$(function() {
$('#form1').formlite( { url: ‘test-ajax.php’ } ); });</script></head><body> <form id="form1" action="test.php" method="POST"> Name: <input type="text" name="user" /> Comment: <input type="text" name="comment" /> <input type="submit" value="Submit" /> </form></body></html>
Example 2
More Options
• target• success
;(function($) {
$.fn.formlite = function(options) { return this.submit(function() {
...
$.ajax({ url: opts.url, type: opts.method, data: $form.serialize(),
success: function(response) { if (opts.target) $(opts.target).html(response); if (opts.success) opts.success(response); // hmmmm.... }
});
return false; });};
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function(options) { return this.submit(function() {
var form = this, $form = $(this);
$.ajax({ url: opts.url, type: opts.method, data: $form.serialize(),
success: function(response) { if (opts.target) $(opts.target).html(response); if (opts.success) opts.success.call(form, response); }
});
return false; });};
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function(options) { return this.submit(function() {
var form = this, $form = $(this);
$.ajax({ url: opts.url, type: opts.method, data: $form.serialize(),
success: function(response) { if (opts.target) $(opts.target).html(response); if (opts.success) opts.success.call(form, response); }
});
return false; });};
})(jQuery);
Example 2
if (opts.success) opts.success.call(form, response);
if (opts.success) opts.success(response);
<html><head><script type=“text/javascript” src=“jquery.formlite.js”></script><script type=“text/javascript”>$(function() { $('#form1').formlite({ target: '#response1' }); $('#form2').formlite({ success: onSuccess }); function onSuccess(response) { // this is the form element $('#response2').html(response); };});</script></head><body> <form id="form1" action="test.php" method="POST"> ... </form> <div id=“response1”></div> <form id="form2" action="test.php" method="POST"> ... </form> <div id=“response2”></div></div></body></html>
Example 2
Example 3
A slideshow plugin
Example 3...$('.slideshow').slideshow();...
<body> <div class="slideshow”> <img src="images/beach1.jpg" /> <img src="images/beach2.jpg" /> <img src="images/beach3.jpg" /> </div> <div class="slideshow"> <img src="images/beach4.jpg" /> <img src="images/beach5.jpg" /> <img src="images/beach6.jpg" /> </div></body>
Example 3$.fn.slideshow = function() { return this.each(function() {
});};
Example 3$.fn.slideshow = function() { return this.each(function() { // ‘this’ is our slideshow container element var $this = $(this); var $slides = $this.children(); var curr = 0, slideCount = $slides.size();
});};
Example 3$.fn.slideshow = function() { return this.each(function() { // ‘this’ is our slideshow container element var $this = $(this); var $slides = $this.children(); var curr = 0, slideCount = $slides.size(); // hide all slides but the first $slides.each(function(i) { // 'this' is the slide element $(this)[i==0 ? 'show' : 'hide'](); });
});};
Example 3$.fn.slideshow = function() { return this.each(function() { // ‘this’ is our slideshow container element var $this = $(this); var $slides = $this.children(); var curr = 0, slideCount = $slides.size(); // hide all slides but the first $slides.each(function(i) { // 'this' is the slide element $(this)[i==0 ? 'show' : 'hide'](); }); function transition() { // private function ... }; setTimeout(transition, 4000); // start the initial timer });};
Example 3$.fn.slideshow = function() { return this.each(function() { ... function transition() { var next = curr == (slideCount - 1) ? 0 : curr + 1;
// fadeOut curr, fadeIn next $($slides[curr]).fadeOut(); $($slides[next]).fadeIn();
// start timer again setTimeout(transition, 4000);
curr = curr == (slideCount - 1) ? 0 : curr + 1; };
// start the initial timer setTimeout(transition, 4000); });};
Options
• timeout• speed
Example 3$.fn.slideshow = function(options) { return this.each(function() { // ‘this’ is our slideshow container element var $this = $(this); // build opts object var opts = $.extend( {}, $.fn.slideshow.defaults, options || {});
...};
// plugin default settings$.fn.slideshow.defaults = { timeout: 4000, speed: 1000};
Example 3$.fn.slideshow = function(options) { return this.each(function() { // ‘this’ is our slideshow container element var $this = $(this); // build opts object
var opts = $.extend( {}, $.fn.slideshow.defaults, options || {}, $.metadata ? $this.metadata() : {}); ...};
// plugin default settings$.fn.slideshow.defaults = { timeout: 4000, speed: 1000};
Example 3
// private function transition() { var next = curr == (slideCount - 1) ? 0 : curr + 1;
// fadeOut curr, fadeIn next $($slides[curr]).fadeOut(opts.speed); $($slides[next]).fadeIn(opts.speed);
// start timer again setTimeout(transition, opts.timeout);
curr = curr == (slideCount - 1) ? 0 : curr + 1; };
Example 3<script type="text/javascript" src="jquery.metadata.js"></script><script type="text/javascript">$.metadata.setType("attr", "data-jquery")
$(function() { $('.slideshow').slideshow();});// $.fn.slideshow.defaults.speed = 500;</script><body> <div class="slideshow"
data-jquery ="{ timeout: 2000, speed: 300 }"> <img src="images/beach1.jpg" /> ... </div> <div class="slideshow"> <img src="images/beach4.jpg" /> ... </div></body>
Tips
• Learn the ‘core’ – don’t reinvent the wheel$.serialize()$.param()$().data(), $().removeData()$.trim()
$.isFunction()
Public vs private (functions and properties)Callbacks and this
Tips
Logging// define log function within your plugin closurefunction log() { if (window.console && window.console.log) window.console.log(
'[pluginName] ' + Array.prototype.join.call(arguments,'')); };
// example from Cycle Plugin if (els.length < 2) { log('terminating; too few slides:', els.length); return; }
Version your plugin$.fn.myPlugin.version = 1;
Tips
• If you publish a plugin...
• Monitor the jQuery mailing list• Have thick skin (don't be defensive)• Respect your users
Thanks!
http://jquery.malsup.com/tae/