`
zhyi_12
  • 浏览: 99880 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

jquery组件创建模式(转载)

 
阅读更多

转自 http://www.learningjquery.com/2007/10/a-plugin-development-pattern

I've been developing jQuery plugins for quite a while now, and I've become rather comfortable with a particular style of plugin development for my scripts. This article is meant to share the pattern that I've found especially useful for plugin authoring. It assumes you already have an understanding of plugin development for jQuery; if you're a novice plugin author, please review the jQuery Authoring Guidelines first.

There are a few requirements that I feel this pattern handles nicely:

  1. Claim only a single name in the jQuery namespace
  2. Accept an options argument to control plugin behavior
  3. Provide public access to default plugin settings
  4. Provide public access to secondary functions (as applicable)
  5. Keep private functions private
  6. Support the Metadata Plugin

I'll cover these requirements one by one, and as we work through them we'll build a simple plugin which highlights text.

Claim only a single name in the jQuery namespace

This implies a single-plugin script. If your script contains multiple plugins, or complementary plugins (like $.fn.doSomething() and $.fn.undoSomething()) then you'll claim multiple names are required. But in general when authoring a plugin, strive to use only a single name to hold all of its implementation details.

In our example plugin we will claim the name "hilight".

JavaScript:
  1. // plugin definition
  2. $.fn.hilight = function() {
  3.   // Our plugin implementation code goes here.
  4. };

And our plugin can be invoked like this:

JavaScript:
  1. $('#myDiv').hilight();

But what if we need to break up our implementation into more than one function? There are many reasons to do so: the design may require it; it may result in a simpler or more readable implementation; and it may yield better OOOO semantics.

It's really quite trivial to break up the implementation into multiple functions without adding noise to the namespace. We do this by recognizing, and taking advantage of, the fact that functions are first-class objects in JavaScript. Like any other object, functions can be assigned properties. Since we have already claimed the "hilight" name in the jQuery prototype object, any other properties or functions that we need to expose can be declared as properties on our "hilight" function. More on this later.

Accept an options argument to control plugin behavior

Let's add support to our hilight plugin for specifying the foreground and background colors to use. We should allow options like these to be passed as an options object to the plugin function. For example:

JavaScript:
  1. // plugin definition
  2. $.fn.hilight = function(options) {
  3.   var defaults = {
  4.     foreground: 'red',
  5.     background: 'yellow'
  6.   };
  7.   // Extend our default options with those provided.
  8.   var opts = $.extend(defaults, options);
  9.  
  10.   // Our plugin implementation code goes here.
  11. };

Now our plugin can be invoked like this:

JavaScript:
  1. $('#myDiv').hilight({
  2.   foreground: 'blue'
  3. });

 

Provide public access to default plugin settings

An improvement we can, and should, make to the code above is to expose the default plugin settings. This is important because it makes it very easy for plugin users to override/customize the plugin with minimal code. And this is where we begin to take advantage of the function object.

JavaScript:
  1. // plugin definition
  2. $.fn.hilight = function(options) {
  3.   // Extend our default options with those provided.
  4.   // Note that the first arg to extend is an empty object -
  5.   // this is to keep from overriding our "defaults" object.
  6.   var opts = $.extend({}, $.fn.hilight.defaults, options);
  7.  
  8.   // Our plugin implementation code goes here.
  9. };
  10.  
  11. // plugin defaults - added as a property on our plugin function
  12. $.fn.hilight.defaults = {
  13.   foreground: 'red',
  14.   background: 'yellow'
  15. };

Now users can include a line like this in their scripts:

JavaScript:
  1. // this need only be called once and does not
  2. // have to be called from within a 'ready' block
  3. $.fn.hilight.defaults.foreground = 'blue';

And now we can call the plugin method like this and it will use a blue foreground color:

JavaScript:
  1. $('#myDiv').hilight();

As you can see, we've allowed the user to write a single line of code to alter the default foreground color of the plugin. And users can still selectively override this new default value when they want:

JavaScript:
  1. // override plugin default foreground color
  2. $.fn.hilight.defaults.foreground = 'blue';
  3.  
  4. ...
  5.  
  6. // invoke plugin using new defaults
  7. $('.hilightDiv').hilight();
  8.  
  9. ...
  10.  
  11. // override default by passing options to plugin method
  12. $('#green').hilight({
  13.   foreground: 'green'
  14. });

 

Provide public access to secondary functions as applicable

This item goes hand-in-hand with the previous item and is an interesting way to extend your plugin (and to let others extend your plugin). For example, the implementation of our plugin may define a function called "format" which formats the hilight text. Our plugin may now look like this, with the default implementation of the format method defined below the hilight function.

JavaScript:
  1. // plugin definition
  2. $.fn.hilight = function(options) {
  3.   // iterate and reformat each matched element
  4.   return this.each(function() {
  5.     var $this = $(this);
  6.     ...
  7.     var markup = $this.html();
  8.     // call our format function
  9.     markup = $.fn.hilight.format(markup);
  10.     $this.html(markup);
  11.   });
  12. };
  13.  
  14. // define our format function
  15. $.fn.hilight.format = function(txt) {'
  16.   return '<strong>' + txt + '</strong>';
  17. };

We could have just as easily supported another property on the options object that allowed a callback function to be provided to override the default formatting. That's another excellent way to support customization of your plugin. The technique shown here takes this a step further by actually exposing the format function so that it can be redefined. With this technique it would be possible for others to ship their own custom overrides of your plugin נin other words, it means others can write plugins for your plugin.

Considering the trivial example plugin we're building in this article, you may be wondering when this would ever be useful. One real-world example is the Cycle Plugin. The Cycle Plugin is a slideshow plugin which supports a number of built-in transition effects נscroll, slide, fade, etc. But realistically, there is no way to define every single type of effect that one might wish to apply to a slide transition. And that's where this type of extensibility is useful. The Cycle Plugin exposes a "transitions" object to which users can add their own custom transition definitions. It's defined in the plugin like this:

JavaScript:
  1. $.fn.cycle.transitions = {
  2.   ...
  3. };

This technique makes it possible for others to define and ship transition definitions that plug-in to the Cycle Plugin.

Keep private functions private

The technique of exposing part of your plugin to be overridden can be very powerful. But you need to think carefully about what parts of your implementation to expose. Once it's exposed, you need to keep in mind that any changes to the calling arguments or semantics may break backward compatibility. As a general rule, if you're not sure whether to expose a particular function, then you probably shouldn't.

So how then do we define more functions without cluttering the namespace and without exposing the implementation? This is a job for closures. To demonstrate, we'll add another function to our plugin called "debug". The debug function will log the number of selected elements to the Firebug console. To create a closure, we wrap the entire plugin definition in a function (as detailed in the jQuery Authoring Guidelines).

JavaScript:
  1. // create closure
  2. (function($) {
  3.   // plugin definition
  4.   $.fn.hilight = function(options) {
  5.     debug(this);
  6.     ...
  7.   };
  8.  
  9.   // private function for debugging
  10.   function debug($obj) {
  11.     if (window.console && window.console.log)
  12.       window.console.log('hilight selection count: ' + $obj.size());
  13.   };
  14.   ...
  15. // end of closure
  16. })(jQuery);

Our "debug" method cannot be accessed from outside of the closure and thus is private to our implementation.

Support the Metadata Plugin

Depending on the type of plugin you're writing, adding support for the Metadata Plugin can make it even more powerful. Personally, I love the Metadata Plugin because it lets you use unobtrusive markup to override plugin options (which is particularly useful when creating demos and examples). And supporting it is very simple!
Update: This bit was optimized per suggestion in the comments.

JavaScript:
  1. // plugin definition
  2. $.fn.hilight = function(options) {
  3.   ...
  4.   // build main options before element iteration
  5.   var opts = $.extend({}, $.fn.hilight.defaults, options);
  6.  
  7.   return this.each(function() {
  8.     var $this = $(this);
  9.     // build element specific options
  10.     var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
  11.     ...

This changed line does a couple of things:

  • it tests to see if the Metadata Plugin is installed
  • if it is installed, it extends our options object with the extracted metadata.

This line is added as the last argument to jQuery.extend so it will override any other option settings. Now we can drive behavior from the markup if we choose:

<!--  markup  -->
<div class="hilight { background: 'red', foreground: 'white' }">
  Have a nice day!
</div>
<div class="hilight { foreground: 'orange' }">
  Have a nice day!
</div>
<div class="hilight { background: 'green' }">
  Have a nice day!
</div>

And now we can hilight each of these divs uniquely using a single line of script:

JavaScript:
  1. $('.hilight').hilight();

 

Putting it All Together

Below is the completed code for our example:

JavaScript:
  1. //
  2. // create closure
  3. //
  4. (function($) {
  5.   //
  6.   // plugin definition
  7.   //
  8.   $.fn.hilight = function(options) {
  9.     debug(this);
  10.    
  11.     // build main options before element iteration
  12.     var opts = $.extend({}, $.fn.hilight.defaults, options);
  13.    
  14.     // iterate and reformat each matched element
  15.     return this.each(function() {
  16.       $this = $(this);
  17.       // build element specific options
  18.       var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
  19.       // update element styles
  20.       $this.css({
  21.         backgroundColor: o.background,
  22.         color: o.foreground
  23.       });
  24.       var markup = $this.html();
  25.       // call our format function
  26.       markup = $.fn.hilight.format(markup);
  27.       $this.html(markup);
  28.     });
  29.   };
  30.  
  31.   //
  32.   // private function for debugging
  33.   //
  34.   function debug($obj) {
  35.     if (window.console &amp;&amp; window.console.log)
  36.       window.console.log('hilight selection count: ' + $obj.size());
  37.   };
  38.  
  39.   //
  40.   // define and expose our format function
  41.   //
  42.   $.fn.hilight.format = function(txt) {
  43.     return '<strong>' + txt + '</strong>';
  44.   };
  45.  
  46.   //
  47.   // plugin defaults
  48.   //
  49.   $.fn.hilight.defaults = {
  50.     foreground: 'red',
  51.     background: 'yellow'
  52.   };

相关推荐

    页面设计jquery组件

    页面设计中的jQuery组件是网页开发中的重要组成部分,它们极大地提升了用户体验和开发者的工作效率。jQuery,一个流行的JavaScript库,简化了DOM操作、事件处理、动画效果和Ajax交互等任务。在这个主题下,我们将...

    cui组件 jquery组件库

    CUI组件库是一款基于jQuery的前端开发框架,旨在简化Web前端开发流程,提供一系列预封装的用户界面元素和交互功能。这款组件库以其易用性、高效性和丰富的功能集为特点,深受开发者喜爱。在本篇文章中,我们将深入...

    jquery组件

    **jQuery组件**是一种基于JavaScript库jQuery的扩展,用于增强网页的交互性和动态功能。jQuery以其简洁易用的API,使得JavaScript编程变得更加简单,而jQuery组件则进一步提供了丰富的UI元素和功能,如数据表格、...

    JQuery 最新组件库

    **jQuery 最新组件库详解** jQuery 是一个广泛使用的JavaScript库,它简化了HTML文档遍历、事件处理、动画以及Ajax交互。随着技术的发展,jQuery也不断更新,推出了各种新的组件,为开发者提供了更为丰富的功能和更...

    jquery 组件大全

    弹出层通常用于显示详细信息、对话框或表单,例如,jQuery Dialog是jQuery UI中的一个功能强大的组件,可以创建模态或非模态对话框。此外,还有其他插件如Bootstrap的Modal,提供更加灵活的配置选项。 3. **弹出...

    ui组件 jquery组合组件

    本资源"ui组件 jquery组合组件"正是一个针对jQuery设计的UI组件集合,特别适合于对旧版本IE(如IE8+)和Chrome浏览器的支持。 首先,让我们深入了解一下jQuery UI组件。jQuery UI提供了一系列可定制的、交互式的UI...

    jquery组件库

    jQuery组件库是开发者基于jQuery框架创建的一系列可复用的代码模块,这些模块通常包括UI组件(如滑块、日历、分页器等)和功能性组件(如表单验证、Ajax请求等)。它们旨在提高开发效率,通过预定义的样式和行为,...

    JQUERY组件 多选框

    本文将深入探讨“JQUERY组件 多选框”,这是一个专门用于实现自定义多选功能的jQuery插件。 一、jQuery多选框概述 jQuery多选框组件允许用户在一个列表中选择多个选项,提供了丰富的自定义功能。它不仅可以替代传统...

    非常有用的jQuery开发组件包

    这个“非常有用的jQuery开发组件包”显然集合了一系列有助于开发人员提高效率、增强网页交互性的工具。以下是对这个组件包中可能包含的内容的详细解释: 1. **jQuery核心库**:组件包中的基础部分肯定是jQuery的...

    jQuery封装的组件

    本文将深入探讨一个基于jQuery封装的组件,通过标题"jQuery封装的组件"我们可以推测,这是一个利用jQuery创建的自定义UI元素或功能模块。描述中的链接指向了一篇博客文章,虽然具体内容无法直接提供,但我们可以根据...

    jQuery UI组件 jQuery UI

    接着,通过jQuery的选择器和`.ui()`方法来激活UI组件,例如创建一个对话框: ```javascript $(function() { $("#dialog").dialog(); }); ``` 同时,jQuery UI 提供了许多可定制的选项,如宽度、高度、是否可拖动、...

    jquery常用组件打包下载

    4. **动画效果**:jQuery的`.animate()`方法使得创建平滑的动画效果变得轻而易举。 5. **Ajax**:jQuery封装了XMLHttpRequest对象,提供了`.ajax()`方法,用于进行异步数据获取,使得前后端交互更为便捷。 接下来,...

    基于jquery的网页组件

    本篇文章将深入探讨如何利用jQuery创建高效的网页组件,以及`cui_1.0.0beta`这个压缩包中可能包含的组件资源。 ### jQuery基础 jQuery的核心理念是“Write Less, Do More”。它通过封装DOM操作、事件处理、动画...

    很炫很酷的Jquery组件

    "很炫很酷的Jquery组件"这个压缩包很可能包含了各种精心设计的jQuery插件和自定义控件,这些都是前端开发中的重要工具,能够帮助开发者创建功能丰富、用户体验优良的BS(Browser-Server,即浏览器-服务器)项目。...

    最新jQueryUI组件下载

    对于前端开发者而言,熟练掌握jQuery UI能有效提高开发效率,创建出更具吸引力的交互界面。而下载的"jquery-ui-1.10.0"文件,应包含该版本的JS、CSS以及可能的示例代码和文档,是学习和使用jQuery UI的好资源。

    jquery_tree 树形组件

    jQuery Tree组件是基于流行的JavaScript库jQuery构建的,它为开发者提供了在网页上创建交互式、可操作的树状结构的能力。这个组件设计精巧,易于集成,功能强大,使得用户可以方便地对层次化的数据进行浏览和管理。 ...

    JQuery常用组件

    内含有: jquery.1.1.4.core.zip --jQuery最新核心代码 jquery.calendar.zip --日历组件 jquery.menu.zip --菜单组件 jquery.tablesorter.zip --表格排序组件 jquery.tabs.zip --标签页组件 ...

    Jquery遮罩层组件

    jQuery 道具库提供了一款名为 "Jquery-reveal" 的遮罩层组件,它简化了实现这一功能的过程,让开发者可以快速、方便地创建具有提示和自定义显示效果的遮罩层。 **一、jQuery 遮罩层基础** 1. **引入资源**:在项目...

    jquery界面组件

    《jQuery界面组件详解》 jQuery,作为一款广泛使用的JavaScript库,极大地简化了DOM操作、事件处理、动画设计和Ajax交互。在网页开发中,jQuery界面组件是提升用户体验、实现复杂交互的重要工具。本文将深入探讨...

    jQuery之尺寸调整组件的深入解析

    jQuery UI则是基于jQuery开发的一套用户界面交互效果的工具包,其中包含了多个可定制的交互组件,而Resizable就是其中一个用于调整尺寸的组件。 Resizable组件使DOM元素能够响应用户的拖动操作而改变尺寸,这在设计...

Global site tag (gtag.js) - Google Analytics