Board logo

标题: 使用 jQuery 创建自己的插件-4 调优插件 [打印本页]

作者: look_w    时间: 2018-8-23 09:40     标题: 使用 jQuery 创建自己的插件-4 调优插件

调优插件网上关于初级插件的大部分文章都到此为止了,这时它们会让您采用基本的插件格式并运行。但是,这种基本架构也太 “基本” 了。在编写插件时还必须考虑另一件重要的事情,给您插件增色所需要的内容远不止一个初级插件那么简单。再多增加两个步骤,您就能将初级插件转换为中级插件。
调优 #1 - 让内部方法私有化在任何面向对象的编程语言中,您会发现创建运行重复代码的外部函数非常方便。在我创建的 NumberFormatter 插件中,有一个这种代码的样例 ——  该代码决定向函数传递哪个地理位置,以及要使用哪些字符作为小数点和分组符。format() 方法和 parse() 方法中都需要该代码,任何一个初级程序员都会告诉您这属于它自己的方法。但是,这会出现一个问题,因为您处理的是 jQuery 插件:如果您使用 JavaScript 中的定义将它作为自己的函数,那么任何人都可以为任何目的使用脚本调用该方法。这不是该函数的目的,我更倾向于不调用它,因为它仅用于内部工作。那么,让我们看看如何将该函数私有化。
这种私有方法问题的解决方案称为 Closure,它可以有效地从外部调用关闭整个插件代码,附加到 jQuery 对象的除外(那些是公共方法)。通过这种设计,您可以将任何代码放入插件中,不用担心被外部脚本调用。通过将插件方法附加到 jQuery 对象,您可以有效地将它们变为公共方法,而让其他的函数/类私有化。清单 6 展示了实现该操作所需的代码。            
清单 6. 私有化函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// this code creates the Closure structure
(function(jQuery) {

   // this function is "private"
   function formatCodes(locale) {
      // plug-in specific code here
   };  // don't forget the semi-colon

   // this method is "public" because it's attached to the jQuery object
    jQuery.fn.format = function(options) {

     var options = jQuery.extend( {

          format: "#,###.00",
          locale: "us"

     },options);

     return this.each(function(){
         var text = new String(jQuery(this).text());
         if (jQuery(this).is(":input"))
             text = new String(jQuery(this).val());

         // you can call the private function like any other function
         var formatData = formatCodes(options.locale.toLowerCase());

         // plug-in-specific code  here
      });
     }; // don't forget the semi-colon to close the method

// this code ends the Closure structure
})(jQuery);




调优 #2 - 让插件的默认值可覆盖调优插件的最后一步是让它可以覆盖默认值。毕竟,如果德国的开发人员下载了该插件,而且了解他的所有 web 应用程序用户希望使用德文版本,那么您应该让他能够使用一行代码修改默认语言环境,而不是要他在每个方法调用中都修改一遍。这样您的插件才会非常方便,因为一个 web 应用程序不太可能使用不同的国际化格式向用户展示数字。您在网页上看一下就知道,所有数字都是使用同一个语言环境的格式。
该步骤要求您修改某处代码,因此您将看到让插件最为耀眼的一步。            
清单 7. 覆盖默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
jQuery.fn.format = function(options) {
// Change how you load your options in to take advantage of your overridable defaults
// You change how your extend() function works, because the defaults
// are globally defined, rather than within the method.  If you didn't use the
// {} as the first argument, you'd copy the options passed in over the defaults, which is
// undesirable.  This {} creates a new temporary object to store the options
// You can simply call the defaults as an object within your plug-in
var options = jQuery.extend({},jQuery.fn.format.defaults, options);

   return this.each(function(){
   
   // rest of the plug-in code here

// define the defaults here as an object in the plug-in
jQuery.fn.format.defaults = {
      format: "#,###.00",
      locale: "us"
      }; // don't forget the semi-colon




这是创建插件的最后一个步骤!这样您就有了一个不错的插件,可以进行最后的测试了。清单 8 展示了您可以放入本文的完整插件,以便您查看这些部分是如何变为一个整体的。此外还包含了 parse() 函数,到目前为止我还没有讨论过该函数,但是它包含在插件中(我没有详细介绍插件处理格式化的部分,因为它们不在本文讨论之列。样例中包含了该部分,插件本身当然也有)。
清单 8. NumberFormatter 插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
(function(jQuery) {

    function FormatData(valid, dec, group, neg) {
       this.valid = valid;
       this.dec = dec;
       this.group = group;
       this.neg = neg;
    };

    function formatCodes(locale) {
      // format logic goes here
      return new FormatData(valid, dec, group, neg);
    };

jQuery.fn.parse = function(options) {

    var options = jQuery.extend({},jQuery.fn.parse.defaults, options);

    var formatData = formatCodes(options.locale.toLowerCase());

    var valid = formatData.valid;
    var dec = formatData.dec;
    var group = formatData.group;
    var neg = formatData.neg;

    var array = [];
    this.each(function(){

       var text = new String(jQuery(this).text());
       if (jQuery(this).is(":input"))
           text = new String(jQuery(this).val());


       // now we need to convert it into a number
       var number = new Number(text.replace(group,'').replace(dec,".").replace(neg,"-"));
       array.push(number);
     });

     return array;
};

jQuery.fn.format = function(options) {

    var options = jQuery.extend({},jQuery.fn.format.defaults, options);  

    var formatData = formatCodes(options.locale.toLowerCase());

    var valid = formatData.valid;
    var dec = formatData.dec;
    var group = formatData.group;
    var neg = formatData.neg;

    return this.each(function(){
       var text = new String(jQuery(this).text());
       if (jQuery(this).is(":input"))
           text = new String(jQuery(this).val());

       // formatting logic goes here

       if (jQuery(this).is(":input"))
           jQuery(this).val(returnString);
       else
           jQuery(this).text(returnString);
    });
};
  
jQuery.fn.parse.defaults = {
    locale: "us"
};

jQuery.fn.format.defaults = {
    format: "#,###.00",
    locale: "us"
};
  
})(jQuery);






欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0