jQuery Plugin Development

Download Report

Transcript jQuery Plugin Development

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 Expressions
Extend jQuery.expr[:] object
• Animations
Extend jQuery.easing or jQuery.fx.speed
Considerations
• Host Environment
Target Audience
Other Libraries installed
Older versions of jQuery
• Documentation
• Extensibility / Flexibility
• Interoperability
Metadata plugin
Easing 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”
• Semicolons
Use ‘em
Conventions
• Namespaces
Choose one (ex: $(...).myPlugin() )
• Plugin closure pattern
;(function($){ /* my code here! */})(jQuery);
• $this, $that ex: var $this = $(this)
• File name
jquery.pluginname.js
The Extension Point
• jQuery.fn
• jQuery.fn === jQuery.prototype
• jQuery.fn.myPlugin = function() …
Getting Started
// a simple no-op plugin
jQuery.fn.myPlugin = function() {
}
Getting Started
// a simple no-op plugin
jQuery.fn.myPlugin = function() {
// what is this?
return this;
};
Honor chaining
Getting Started
// a simple no-op plugin
jQuery.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.
<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
<div><h1>Heading
<div><h1>Heading
</div>
<div id=“main">
<div><h1>Heading
<div><h1>Heading
<div><h1>Heading
</div>
</body>
</html>
Example 1
One</h1>content ...</div>
Two</h1>content ...</div>
Three</h1>content ...</div>
One</h1>content ...</div>
Two</h1>content ...</div>
Three</h1>content ...</div>
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>
...
return this.hover(function()
{
...
});
...
this.hover(function() {
...
});
return this;
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
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>
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>
Example 2
;(function($) {
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function() {
};
})(jQuery);
Example 2
;(function($) {
$.fn.formlite = function() {
return this.submit(function() {
...
return this.submit(function() {
...
});
});
};
})(jQuery);
...
this.submit(function() {
...
});
return this;
Example 2
;(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);
jquery.formlite.js
;(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);
Example 2
<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>
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($) {
Example 2
$.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>
More Options
• target
• success
;(function($) {
Example 2
$.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);
;(function($) {
Example 2
$.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);
}
if (opts.success)
});
opts.success(response);
return false;
});
};
})(jQuery);
if (opts.success)
opts.success.call(form, response);
Example 2
<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 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>
/>
/>
/>
/>
/>
/>
$.fn.slideshow = function() {
return this.each(function() {
});
};
Example 3
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;
};
<script type="text/javascript"
src="jquery.metadata.js"></script>
<script type="text/javascript">
$.metadata.setType("attr", "data-jquery")
Example 3
$(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
Version your plugin
$.fn.myPlugin.version = 1;
Logging
// define log function within your plugin closure
function 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;
}
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/