`
dingchao.lonton
  • 浏览: 49782 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

用jquery如何扩展自己的插件

阅读更多

 

 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的车牌插件”是这个库的一个扩展,专门针对车牌号码输入场景进行优化,提供了更加友好和高效的用户体验。 这款基于jQuery的车牌输入插件设计目标是让用户在网页上输入车牌号码时,能够享受到如同原生应用...

    jQuery1.3 DW插件

    **jQuery1.3 DW插件** 是一个专为Dreamweaver(DW)用户设计的扩展,主要用于提升在DW环境中编写jQuery代码的效率。这个插件是针对DW CS3版本优化的,它集成了jQuery 1.3版本的功能,提供了一个方便的自动提示工具,...

    jquery-ui插件

    jQuery UI是一个基于JavaScript的开源库,它是jQuery库的扩展,提供了丰富的用户界面组件和交互效果。这个插件以其强大的功能、易于使用的API和可定制的主题而受到开发者的广泛欢迎。在本文中,我们将深入探讨jQuery...

    浅析JQuery框架及其插件应用

    6. **可扩展性**:JQuery框架具有良好的扩展性,支持开发者创建自己的插件,以满足特定需求。 #### 三、jQuery插件的应用 JQuery插件是基于JQuery核心库构建的扩展模块,旨在增强或补充JQuery的功能,实现特定的...

    jQuery日期选择插件

    jQuery日期选择插件是这个库的一个扩展,为网页表单提供了直观、用户友好的日期输入方式。本篇文章将深入探讨jQuery日期选择插件的相关知识点,包括其功能、使用方法、常见插件及其优点。 ### 1. jQuery日期选择器...

    使用jQuery.form插件,实现完美的表单异步提交

    jQuery.form插件正是为了满足这种需求而设计的,它扩展了jQuery库,使表单异步提交变得更加简单、灵活且强大。本文将详细介绍如何使用jQuery.form插件,实现完美的表单异步提交。 首先,我们需要了解jQuery.form...

    JQuery 倒计时插件

    使用JQuery倒计时插件,开发者可以轻松实现以下功能: 1. **设置目标时间**:用户可以设定一个未来的时间点,插件会计算出从当前时间到目标时间的剩余秒数、分钟数、小时数和天数,并实时更新。 2. **自定义样式**:...

    jquery 日期 时间 插件

    而“jquery 日期时间插件”则是在jQuery基础上开发的扩展,用于增强网页应用程序对日期和时间的选择功能。这类插件通常提供用户友好的界面,允许用户方便地选择日期和时间,极大地提升了用户体验。 这篇内容将详细...

    jQuery-searchableSelect插件

    使用jQuery-searchableSelect插件,首先需要引入jQuery库和插件的JavaScript文件,以及可选的CSS样式文件。然后,对需要应用插件的`select`元素调用`.searchableSelect()`方法。以下是一个简单的示例: ```html &lt;!...

    jQuery 提示框插件

    jQuery提示框插件是Web开发中的一个实用工具,它扩展了基本的JavaScript功能,使得在网页上创建交互式、美观的提示信息变得简单易行。这些插件通常提供丰富的自定义选项,包括样式、动画效果、位置控制以及与用户...

    jquery文档预览功能插件

    jQuery作为一个广泛使用的JavaScript库,提供了许多便利的插件来简化这种功能的实现。本篇文章将深入讲解“jQuery文档预览功能插件”,并结合示例代码,帮助开发者快速理解并应用。 ### 1. 插件介绍 jQuery Zoho ...

    jquery颜色选择插件

    本教程将详细讲解基于jQuery的颜色选择插件,它旨在模仿Photoshop中的颜色选择器功能,为网页应用提供类似的专业级颜色选取体验。 一、jQuery颜色选择插件的基本原理 jQuery颜色选择插件是通过JavaScript和CSS来...

    JQuery倒计时插件

    jQuery作为一个广泛使用的JavaScript库,提供了丰富的插件来帮助开发者实现这些功能。本篇文章将详细探讨一个名为“jQuery倒计时插件”的工具,以及如何利用它来创建动态的倒计时效果。 首先,我们需要了解jQuery库...

    教你如何做一个自己的jQuery插件,jQuery扩展笔记

    这篇文章将指导你如何构建一个自己的jQuery插件,理解jQuery扩展的核心原理。 首先,我们要明白jQuery插件的本质是一个包装在jQuery对象上的函数。在jQuery中,我们经常看到这样的匿名函数结构: ```javascript ...

    常见jquery图片轮播插件

    在网页设计中,图片轮播是一种常见的展示方式,它能够以动态的形式呈现多张...选择并正确使用这些插件,能极大地提升网站的互动性和吸引力。在开发过程中,理解其工作原理并熟练运用,可以帮助我们更高效地完成项目。

    jquery语法高亮插件

    使用这个jQuery语法高亮插件,开发者可以轻松地在网页上创建吸引人的代码展示区域,提高代码的可读性,同时提升用户体验。无论是用于博客文章、教程还是在线代码编辑器,它都是一个非常实用的工具。要开始使用,只需...

    Jquery和jquery的常用插件

    这些插件进一步扩展了jQuery的功能,提供了更多实用的组件和功能,以满足Web开发中的各种需求。 1. **zTree**:zTree是一个强大的基于jQuery的树形插件,广泛应用于网站的导航菜单、数据展示、文件目录管理等场景。...

    jquery.kxbdmarquee插件

    在这个库的基础上,开发者创建了许多插件来扩展其功能,其中`jquery.kxbdmarquee`就是一款实现无缝滚动效果的插件。无缝滚动是一种常见的网页元素动态展示方式,它能让内容在页面上不间断地滚动,为用户带来流畅的...

    jquery表格树插件

    `jQuery表格树插件`就是为此目的设计的工具,它通过jQuery库实现了将表格转化为可扩展和折叠的树状视图,便于用户交互和信息查找。 **1. 插件功能** 1. **单击行**:用户单击表格中的某一行时,该行可能会展开或...

    jquery下拉刷新插件

    **jQuery 下拉刷新插件详解** 在Web开发中,为了提供与移动应用类似的用户体验,下拉刷新功能变得越来越...在实际开发过程中,可以根据项目需求选择适合的jQuery下拉刷新插件,并根据插件的文档进行详细配置和扩展。

Global site tag (gtag.js) - Google Analytics