Getting Started
To write a jQuery plugin, start by adding a new function property to
the jQuery.fn object where the name of the property is the name of your
plugin:
jQuery.fn.myPlugin = function() {
// Do your awesome plugin stuff here
};
But wait! Where's my awesome dollar sign that I know and love? It's
still there, however to make sure that your plugin doesn't collide with
other libraries that might use the dollar sign, it's a best practice to
pass jQuery to an IIFE (Immediately Invoked Function Expression) that
maps it to the dollar sign so it can't be overwritten by another library
in the scope of its execution.
(function( $ ) {
$.fn.myPlugin = function() {
// Do your awesome plugin stuff here
};
})( jQuery );
Ah, that's better. Now within that closure, we can use the dollar sign in place of jQuery as much as we like.
Context
Now that we have our shell we can start writing our actual plugin
code. But before we do that, I'd like to say a word about context. In
the immediate scope of the plugin function, the this
keyword refers to the jQuery object the plugin was invoked on. This is a
common slip up due to the fact that in other instances where jQuery
accepts a callback, the this
keyword refers to the native DOM element. This often leads to developers unnecessarily wrapping the this
keyword (again) in the jQuery function.
(function( $ ){
$.fn.myPlugin = function() {
// there's no need to do $(this) because
// "this" is already a jquery object
// $(this) would be the same as $($('#element'));
this.fadeIn('normal', function(){
// the this keyword is a DOM element
});
};
})( jQuery );
$('#element').myPlugin();
The Basics
Now that we understand the context of jQuery plugins, let's write a plugin that actually does something.
(function( $ ){
$.fn.maxHeight = function() {
var max = 0;
this.each(function() {
max = Math.max( max, $(this).height() );
});
return max;
};
})( jQuery );
var tallest = $('div').maxHeight(); // Returns the height of the tallest div
This is a simple plugin that leverages .height()
to return the height of the tallest div in the page.
Maintaining Chainability
The previous example returns an integer value of the tallest div on
the page, but often times the intent of a plugin is simply modify the
collection of elements in some way, and pass them along to the next
method in the chain. This is the beauty of jQuery's design and is one of
the reasons jQuery is so popular. So to maintain chainability in a
plugin, you must make sure your plugin returns the this
keyword.
(function( $ ){
$.fn.lockDimensions = function( type ) {
return this.each(function() {
var $this = $(this);
if ( !type || type == 'width' ) {
$this.width( $this.width() );
}
if ( !type || type == 'height' ) {
$this.height( $this.height() );
}
});
};
})( jQuery );
$('div').lockDimensions('width').css('color', 'red');
Because the plugin returns the this
keyword in its
immediate scope, it maintains chainability and the jQuery collection can
continue to be manipulated by jQuery methods, such as .css
. So if your plugin doesn't return an intrinsic value, you should always return the this
keyword in the immediate scope of the plugin function. Also, as you
might assume, arguments you pass in your plugin invocation get passed to
the immediate scope of the plugin function. So in the previous example,
the string 'width' becomes the type argument for the plugin function.
Defaults and Options
For more complex and customizable plugins that provide many options,
it's a best practice to have default settings that can get extended
(using $.extend
)
when the plugin is invoked. So instead of calling a plugin with a large
number of arguments, you can call it with one argument which is an
object literal of the settings you would like to override. Here's how
you do it.
(function( $ ){
$.fn.tooltip = function( options ) {
// Create some defaults, extending them with any options that were provided
var settings = $.extend( {
'location' : 'top',
'background-color' : 'blue'
}, options);
return this.each(function() {
// Tooltip plugin code here
});
};
})( jQuery );
$('div').tooltip({
'location' : 'left'
});
In this example, after calling the tooltip plugin with the given
options, the default location setting gets overridden to become 'left'
, while the background-color setting remains the default 'blue'
. So the final settings object ends up looking like this:
{
'location' : 'left',
'background-color' : 'blue'
}
This is a great way to offer a highly configurable plugin without requiring the developer to define all available options.
Namespacing
Properly namespacing your plugin is a very important part of plugin
development. Namespacing correctly assures that your plugin will have a
very low chance of being overwritten by other plugins or code living on
the same page. Namespacing also makes your life easier as a plugin
developer because it helps you keep better track of your methods, events
and data.
Plugin Methods
Under no circumstance should a single plugin ever claim more than one namespace in the jQuery.fn
object.
(function( $ ){
$.fn.tooltip = function( options ) {
// THIS
};
$.fn.tooltipShow = function( ) {
// IS
};
$.fn.tooltipHide = function( ) {
// BAD
};
$.fn.tooltipUpdate = function( content ) {
// !!!
};
})( jQuery );
This is a discouraged because it clutters up the $.fn
namespace. To remedy this, you should collect all of your plugin's
methods in an object literal and call them by passing the string name of
the method to the plugin.
(function( $ ){
var methods = {
init : function( options ) {
// THIS
},
show : function( ) {
// IS
},
hide : function( ) {
// GOOD
},
update : function( content ) {
// !!!
}
};
$.fn.tooltip = function( method ) {
// Method calling logic
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})( jQuery );
// calls the init method
$('div').tooltip();
// calls the init method
$('div').tooltip({
foo : 'bar'
});
// calls the hide method
$('div').tooltip('hide');
// calls the update method
$('div').tooltip('update', 'This is the new tooltip content!');
This type of plugin architecture allows you to encapsulate all of
your methods in the plugin's parent closure, and call them by first
passing the string name of the method, and then passing any additional
parameters you might need for that method. This type of method
encapsulation and architecture is a standard in the jQuery plugin
community and it used by countless plugins, including the plugins and
widgets in jQueryUI.
Events
A lesser known feature of the bind
method is that is allows for namespacing of bound events. If your
plugin binds an event, its a good practice to namespace it. This way, if
you need to unbind
it later, you can do so without interfering with other events that
might have been bound to the same type of event. You can namespace your
events by appending “.<namespace>” to the type of event you're
binding.
(function( $ ){
var methods = {
init : function( options ) {
return this.each(function(){
$(window).bind('resize.tooltip', methods.reposition);
});
},
destroy : function( ) {
return this.each(function(){
$(window).unbind('.tooltip');
})
},
reposition : function( ) {
// ...
},
show : function( ) {
// ...
},
hide : function( ) {
// ...
},
update : function( content ) {
// ...
}
};
$.fn.tooltip = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})( jQuery );
$('#fun').tooltip();
// Some time later...
$('#fun').tooltip('destroy');
In this example, when the tooltip is initialized with the init
method, it binds the reposition method to the resize event of the window
under the namespace 'tooltip'. Later, if the developer needs to destroy
the tooltip, we can unbind the events bound by the plugin by passing
its namespace, in this case 'tooltip', to the unbind method. This allows
us to safely unbind plugin events without accidentally unbinding events
that may have been bound outside of the plugin.
Data
Often times in plugin development, you may need to maintain state or
check if your plugin has already been initialized on a given element.
Using jQuery's data
method is a great way to keep track of variables on a per element
basis. However, rather than keeping track of a bunch of separate data
calls with different names, it's best to use a single object literal to
house all of your variables, and access that object by a single data
namespace.
(function( $ ){
var methods = {
init : function( options ) {
return this.each(function(){
var $this = $(this),
data = $this.data('tooltip'),
tooltip = $('<div />', {
text : $this.attr('title')
});
// If the plugin hasn't been initialized yet
if ( ! data ) {
/*
Do more setup stuff here
*/
$(this).data('tooltip', {
target : $this,
tooltip : tooltip
});
}
});
},
destroy : function( ) {
return this.each(function(){
var $this = $(this),
data = $this.data('tooltip');
// Namespacing FTW
$(window).unbind('.tooltip');
data.tooltip.remove();
$this.removeData('tooltip');
})
},
reposition : function( ) { // ... },
show : function( ) { // ... },
hide : function( ) { // ... },
update : function( content ) { // ...}
};
$.fn.tooltip = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})( jQuery );
Using data helps you keep track of variables and state across method
calls from your plugin. Namespacing your data into one object literal
makes it easy to access all of your plugin's properties from one central
location, as well as reducing the data namespace which allows for easy
removal if need be.
Summary and Best Practices
Writing jQuery plugins allows you to make the most out of the library
and abstract your most clever and useful functions out into reusable
code that can save you time and make your development even more
efficient. Here's a brief summary of the post and what to keep in mind
when developing your next jQuery plugin:
- Always wrap your plugin in a closure:
(function( $ ){ /* plugin goes here */ })( jQuery );
- Don't redundantly wrap the
this
keyword in the immediate scope of your plugin's function
- Unless you're returning an intrinsic value from your plugin, always have your plugin's function return the
this
keyword to maintain chainability.
- Rather than requiring a lengthy amount of arguments, pass your
plugin settings in an object literal that can be extended over the
plugin's defaults.
- Don't clutter the
jQuery.fn
object with more than one namespace per plugin.
- Always namespace your methods, events and data.
分享到:
相关推荐
而“jQuery的车牌插件”是这个库的一个扩展,专门针对车牌号码输入场景进行优化,提供了更加友好和高效的用户体验。 这款基于jQuery的车牌输入插件设计目标是让用户在网页上输入车牌号码时,能够享受到如同原生应用...
**jQuery1.3 DW插件** 是一个专为Dreamweaver(DW)用户设计的扩展,主要用于提升在DW环境中编写jQuery代码的效率。这个插件是针对DW CS3版本优化的,它集成了jQuery 1.3版本的功能,提供了一个方便的自动提示工具,...
jQuery UI是一个基于JavaScript的开源库,它是jQuery库的扩展,提供了丰富的用户界面组件和交互效果。这个插件以其强大的功能、易于使用的API和可定制的主题而受到开发者的广泛欢迎。在本文中,我们将深入探讨jQuery...
6. **可扩展性**:JQuery框架具有良好的扩展性,支持开发者创建自己的插件,以满足特定需求。 #### 三、jQuery插件的应用 JQuery插件是基于JQuery核心库构建的扩展模块,旨在增强或补充JQuery的功能,实现特定的...
jQuery日期选择插件是这个库的一个扩展,为网页表单提供了直观、用户友好的日期输入方式。本篇文章将深入探讨jQuery日期选择插件的相关知识点,包括其功能、使用方法、常见插件及其优点。 ### 1. jQuery日期选择器...
jQuery.form插件正是为了满足这种需求而设计的,它扩展了jQuery库,使表单异步提交变得更加简单、灵活且强大。本文将详细介绍如何使用jQuery.form插件,实现完美的表单异步提交。 首先,我们需要了解jQuery.form...
使用JQuery倒计时插件,开发者可以轻松实现以下功能: 1. **设置目标时间**:用户可以设定一个未来的时间点,插件会计算出从当前时间到目标时间的剩余秒数、分钟数、小时数和天数,并实时更新。 2. **自定义样式**:...
而“jquery 日期时间插件”则是在jQuery基础上开发的扩展,用于增强网页应用程序对日期和时间的选择功能。这类插件通常提供用户友好的界面,允许用户方便地选择日期和时间,极大地提升了用户体验。 这篇内容将详细...
使用jQuery-searchableSelect插件,首先需要引入jQuery库和插件的JavaScript文件,以及可选的CSS样式文件。然后,对需要应用插件的`select`元素调用`.searchableSelect()`方法。以下是一个简单的示例: ```html <!...
jQuery提示框插件是Web开发中的一个实用工具,它扩展了基本的JavaScript功能,使得在网页上创建交互式、美观的提示信息变得简单易行。这些插件通常提供丰富的自定义选项,包括样式、动画效果、位置控制以及与用户...
jQuery作为一个广泛使用的JavaScript库,提供了许多便利的插件来简化这种功能的实现。本篇文章将深入讲解“jQuery文档预览功能插件”,并结合示例代码,帮助开发者快速理解并应用。 ### 1. 插件介绍 jQuery Zoho ...
本教程将详细讲解基于jQuery的颜色选择插件,它旨在模仿Photoshop中的颜色选择器功能,为网页应用提供类似的专业级颜色选取体验。 一、jQuery颜色选择插件的基本原理 jQuery颜色选择插件是通过JavaScript和CSS来...
jQuery作为一个广泛使用的JavaScript库,提供了丰富的插件来帮助开发者实现这些功能。本篇文章将详细探讨一个名为“jQuery倒计时插件”的工具,以及如何利用它来创建动态的倒计时效果。 首先,我们需要了解jQuery库...
这篇文章将指导你如何构建一个自己的jQuery插件,理解jQuery扩展的核心原理。 首先,我们要明白jQuery插件的本质是一个包装在jQuery对象上的函数。在jQuery中,我们经常看到这样的匿名函数结构: ```javascript ...
在网页设计中,图片轮播是一种常见的展示方式,它能够以动态的形式呈现多张...选择并正确使用这些插件,能极大地提升网站的互动性和吸引力。在开发过程中,理解其工作原理并熟练运用,可以帮助我们更高效地完成项目。
使用这个jQuery语法高亮插件,开发者可以轻松地在网页上创建吸引人的代码展示区域,提高代码的可读性,同时提升用户体验。无论是用于博客文章、教程还是在线代码编辑器,它都是一个非常实用的工具。要开始使用,只需...
这些插件进一步扩展了jQuery的功能,提供了更多实用的组件和功能,以满足Web开发中的各种需求。 1. **zTree**:zTree是一个强大的基于jQuery的树形插件,广泛应用于网站的导航菜单、数据展示、文件目录管理等场景。...
在这个库的基础上,开发者创建了许多插件来扩展其功能,其中`jquery.kxbdmarquee`就是一款实现无缝滚动效果的插件。无缝滚动是一种常见的网页元素动态展示方式,它能让内容在页面上不间断地滚动,为用户带来流畅的...
`jQuery表格树插件`就是为此目的设计的工具,它通过jQuery库实现了将表格转化为可扩展和折叠的树状视图,便于用户交互和信息查找。 **1. 插件功能** 1. **单击行**:用户单击表格中的某一行时,该行可能会展开或...
**jQuery 下拉刷新插件详解** 在Web开发中,为了提供与移动应用类似的用户体验,下拉刷新功能变得越来越...在实际开发过程中,可以根据项目需求选择适合的jQuery下拉刷新插件,并根据插件的文档进行详细配置和扩展。