Skip to content

Commit 583ee4b

Browse files
ericladdajpiano
authored andcommitted
refresh basic plugins; added utility plugin method example
1 parent 86d6cc8 commit 583ee4b

File tree

1 file changed

+78
-27
lines changed

1 file changed

+78
-27
lines changed

page/plugins/basic-plugin-creation.md

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title : How to create a basic plugin
2+
title : How to Create a Basic Plugin
33
level: intermediate
44
source: http://jqfundamentals.com/legacy
55
attribution:
@@ -9,19 +9,23 @@ Sometimes you want to make a piece of functionality available throughout your co
99
for example, perhaps you want a single method you can call on a jQuery selection that performs a series of operations on the selection. Maybe you wrote a really useful utility function that you want to be able to move easily to other projects.
1010
In this case, you may want to write a plugin.
1111

12-
##How jQuery works 101
12+
##How jQuery Works 101: jQuery Object Methods and Utility Methods
1313

1414
Before we write our own plugins, we must first understand a little about how jQuery works. Take a look at this code:
1515

1616
```
17-
$('a').css('color','red');
17+
var userColor = window.prompt('Please enter a color:', '');
18+
$('a').css('color', $.trim(userColor));
1819
```
1920

20-
This is some pretty basic jQuery code, but do you know what's happening behind the scenes? Whenever you use the `$` function to select elements, it returns an object. This object contains all of the methods you've been using (`css()`, `click()`, etc.), and all of the elements that fit your selector. The `$` function gets the methods from the `$.fn` object. This object contains all of the jQuery methods, and If we want to write our own methods, it will need to contain those as well.
21+
This is some pretty basic jQuery code, but do you know what's happening behind the scenes? Whenever you use the `$` function to select elements, it returns a jQuery object. This object contains all of the methods you've been using (`css()`, `click()`, etc.), and all of the elements that fit your selector. The jQuery object gets these methods from the `$.fn` object. This object contains all of the jQuery object methods, and if we want to write our own methods, it will need to contain those as well.
2122

22-
##Basic plugin authoring
23+
Additionally the jQuery utility method `$.trim()` is used above to remove any leading or trailing empty space characters from the user input. Utility methods are functions that reside directly on
24+
`$` function itself. You may occasionally want to write a utility method plugin when your extension to the jQuery API does not have to do something to a set of DOM elements you've retrieved.
2325

24-
Let's say we want to create a plugin that makes text green. All we have to do is add a function called `greenify` to `$.fn` and it will available just like any other method.
26+
##Basic Plugin Authoring
27+
28+
Let's say we want to create a plugin that makes text within a set of retrieved elements green. All we have to do is add a function called `greenify` to `$.fn` and it will available just like any other jQuery object method.
2529

2630
```
2731
$.fn.greenify = function () {
@@ -31,50 +35,87 @@ $.fn.greenify = function () {
3135
$('a').greenify(); // makes all the links green
3236
```
3337

34-
Notice that to use `css()`, another method, we use `this`, not `$(this)`. This is because our `greenify` function is a part of the same object as `css()`.
38+
Notice that to use `css()`, another jQuery object method, we use `this`, not `$(this)`. This is because our `greenify` function is a part of the same jQuery object as `css()`.
39+
40+
Additionally suppose we'd like to be more selective in our string trimming and provide for left trim (remove empty space characters at the beginning of the string) and right trim (remove empty space characters from the end of the string) methods. We can create `$.ltrim()` and `$.rtrim()` utility methods by attaching them directly to the `$` function:
41+
42+
```
43+
// Attach ltrim and rtrim directly to the $ function
44+
$.ltrim = function(str) {return str.replace(/^\s+/, '')}
45+
$.rtrim = function(str) {return str.replace(/\s+$/, '')}
46+
47+
var myString = ' jQuery plugins are fun and easy! ';
48+
console.log($.ltrim(myString));
49+
console.log($.rtrim(myString));
50+
```
51+
52+
jQuery's `$.extend()` method provides another alternative for creating new utility methods. When `$.extend()` is passed a single object, the contents of that object are merged with the `$` function.
53+
54+
```
55+
// Have $.extend() attach ltrim and rtrim to the $ function
56+
$.extend({
57+
ltrim : function(str) {return str.replace(/^\s+/, '')},
58+
rtrim : function(str) {return str.replace(/\s+$/, '')}
59+
});
60+
61+
// $.ltrim and $.rtrim defined in this snippet behave
62+
// the same as in the snippet above
63+
var myString = ' jQuery plugins are fun and easy! ';
64+
console.log($.ltrim(myString));
65+
console.log($.rtrim(myString));
66+
```
3567

3668
##Chaining
3769

38-
This works, but there's a couple of things we need to do for our plugin to survive in the real world. One of jQuery's features is chaining, when you link five or six actions onto one selector. This is accomplished by having all jQuery methods return the original jQuery object again (there are a few exeptions: `width()` called without parameters returns the width of the selected element, and is not chainable). Making our plugin chainable takes one line of code:
70+
This works, but there's a couple of things we need to do for our plugin to survive in the real world. One of jQuery's features is chaining, when you link five or six actions onto one selector. This is accomplished by having all jQuery object methods return the original jQuery object again (there are a few exeptions: `width()` called without parameters returns the width of the selected element, and is not chainable). Making our plugin method chainable takes one line of code:
3971

4072
```
4173
$.fn.greenify = function () {
4274
this.css('color','green');
43-
return this;
75+
return this; // enables chaining with other jQuery object methods
4476
}
4577
4678
$('a').greenify().addClass('greenified');
4779
```
4880

49-
##Adding scope
81+
Note that the notion of chaining is *not* applicable to jQuery utility methods like `$.trim()`.
82+
83+
84+
##Protecting the $ Alias and Adding Scope
5085

51-
The `$` variable is very popular among javascript libraries, and if you're using one with jQuery, you will have to make jQuery not use the `$` with `jQuery.noConflict()`. However, this will break our plugin. To work well with other plugins, _and_ still use the jQuery `$` variable, we need to put all of our code inside of an [Immediately Invoked Function Expression](http://stage.learn.jquery.com/javascript-101/functions/#immediately-invoked-function-expression), and then pass the function `jQuery`, and name the parameter `$`:
86+
The `$` variable is very popular among JavaScript libraries, and if you're using another library with jQuery, you will have to make jQuery not use the `$` with `jQuery.noConflict()`. However, this will break our plugin since it is written with the assumption that `$` is an alias to the `jQuery` function. To work well with other plugins, _and_ still use the jQuery `$` alias, we need to put all of our code inside of an [Immediately Invoked Function Expression](http://stage.learn.jquery.com/javascript-101/functions/#immediately-invoked-function-expression), and then pass the function `jQuery`, and name the parameter `$`:
5287

5388
```
5489
(function ($) {
90+
91+
// We can safely use the $ alias inside the Immediately Invoked Function
5592
$.fn.greenify = function () {
5693
this.css('color','green');
5794
return this;
5895
}
96+
97+
$.ltrim = function(str) {return str.replace(/^\s+/, '')}
98+
$.rtrim = function(str) {return str.replace(/\s+$/, '')}
99+
59100
}(jQuery));
60101
```
61102

62103
In addition, the primary purpose of an Immediately Invoked Function is to allow us to have our own private variables. Pretend we want a different color green, and we want to store it in a variable.
63104

64105
```
65106
(function ($) {
66-
var shade = '#556B2F';
107+
var shade = '#556B2F'; // private variable
67108
68109
$.fn.greenify = function () {
69-
this.css('color',shade);
110+
this.css('color', shade);
70111
return this;
71112
}
72113
}(jQuery));
73114
```
74115

75116
##Minimizing Plugin Footprint
76117

77-
It's good practice when writing plugins to only take up one slot within `$.fn`. This reduces both the chance that your plugin will be overriden, and the chance that your plugin will override other plugins. In other words, this is bad:
118+
It's good practice when writing plugins to only take up one slot within `$.fn`. This reduces both the chance that your plugin will be overridden, and the chance that your plugin will override other plugins. In other words, this is bad:
78119

79120
```
80121
(function ($) {
@@ -104,11 +145,15 @@ It would be much better to have one slot, and use parameters to control what act
104145
}(jQuery));
105146
```
106147

148+
<<<<<<< HEAD
107149
##Using the each() method
150+
=======
151+
##Using the each() Method
152+
>>>>>>> refresh basic plugins; added utility plugin method example
108153
109154
Your typical jQuery object will contain references to any number of DOM
110155
elements, and that's why jQuery objects are often referred to as collections.
111-
If you want to do any manipulating with specific elements (eg: getting data an
156+
If you want to do any manipulating with specific elements (eg: getting an
112157
attribute, calculating specific positions) then you need to use `each()` to
113158
loop through the elements.
114159

@@ -121,20 +166,24 @@ $.fn.myNewPlugin = function() {
121166
```
122167

123168
Notice that we return the results of `each()` instead of returning `this`.
124-
Since `each()` is already chainable, it returns `this`, which we then return.
125-
This is a better way to maintain chainability than what we've been doing so far.
169+
Since `each()` is already chainable, it returns `this`, which we then return as
170+
the return value from our plugin method. This is a better way to maintain chainability
171+
than what we've been doing so far.
126172

127-
##Accepting options
173+
##Accepting Options
128174

129-
As your plugins get more and more complex, it's a good idea to make your plugin
130-
customizable by accepting options. The easiest way do this, especially if there
175+
As your plugins get more and more complex, it's a good idea to make them
176+
customizable by having them accept options. The easiest way do this, especially if there
131177
are lots of options, is with an object literal. Let's change our greenify plugin to
132178
accept some options.
133179

134180
```
135181
(function ($) {
182+
136183
$.greenify = function (options) {
137-
// This is the easiest way to have default options.
184+
185+
// This is the easiest way to have default options. $.extend
186+
// will blend the options passed in with the defaults below
138187
var settings = $.extend( {
139188
'color' : '#556B2F', // These are the defaults
140189
'background-color' : 'white'
@@ -145,7 +194,9 @@ accept some options.
145194
'color': settings['color'],
146195
'background-color': settings['background-color']
147196
});
197+
148198
};
199+
149200
}(jQuery));
150201
```
151202

@@ -157,9 +208,9 @@ $('div').greenify({
157208
});
158209
```
159210

160-
The default value for `color` of `#556B2F` gets overriden by `$.extend` to be orange.
211+
The default value for `color` of `#556B2F` gets overriden by `$.extend()` to be orange.
161212

162-
##Putting it together
213+
##Putting It Together
163214

164215
Here's an example of a small plugin using some of the techniques
165216
we've discussed:
@@ -168,7 +219,7 @@ we've discussed:
168219
(function($){
169220
$.fn.showLinkLocation = function() {
170221
return this.filter('a').each(function(){
171-
$(this).append( ' (' + $(this).attr('href') + ')');
222+
$(this).append( ' [' + $(this).attr('href') + ']');
172223
});
173224
};
174225
}(jQuery));
@@ -185,7 +236,7 @@ href attribute in brackets.
185236
<a href="page.html">Foo</a>
186237
187238
<!-- After plugin is called: -->
188-
<a href="page.html">Foo (page.html)</a>
239+
<a href="page.html">Foo [page.html]</a>
189240
```
190241

191242
Our plugin can be optimized though:
@@ -194,13 +245,13 @@ Our plugin can be optimized though:
194245
(function($){
195246
$.fn.showLinkLocation = function() {
196247
return this.filter('a').append(function(){
197-
return ' (' + this.href + ')';
248+
return ' [' + this.href + ']';
198249
});
199250
};
200251
}(jQuery));
201252
```
202253

203-
We're using the `append` method's capability to accept a callback, and the
254+
We're using the `append()` method's capability to accept a callback, and the
204255
return value of that callback will determine what is appended to each element
205256
in the collection. Notice also that we're not using the `attr` method to
206257
retrieve the href attribute, because the native DOM API gives us easy access

0 commit comments

Comments
 (0)