JS 控件 jQuery扩展函数


概述:

jQuery 作为一个轻量级框架,插件格式的控件使用起来非常方便,但是我们基于jQuery写一套控件,需要我们扩展一些函数,便于控件的继承和扩展。

扩展函数:

1.         augment(Function r,Object s1): 将指定的方法或属性放到构造函数的原型链上, 函数支持多于2个变量,后面的变量同s1一样将其成员复制到构造函数的原型链上。

2.         cloneObject(Object obj): 拷贝对象(深拷贝)

jQuery 有一个clone方法,但是只支持HTMLElement,而我们在很多时候需要的是深拷贝对象。

3.         guid(prefix): 生成唯一的id

用于控件生成时,需要用id管理控件

4.         extend(Function subclass,Function superclass,Object overrides): 实现类的继承

这个方法是继承的核心方法,在前面讲过,具体的细节查看前面的博客

5.         merge(Object obj1,Object obj2....): 将多个对象的属性复制到一个新的对象上,如果第一个参数是true,那么实现的是深拷贝。

6.         mix():封装 jQuery.extend 方法,将多个对象的属性merge到第一个对象中

7.         mixin(Function c,Array mixins,Array attrs): 将其他类作为扩展,集成到指定的类上面。

8.         substitue(String str,Object o,[RegExp regexp]) 替换字符串中的字段,用于简单模板

上面是为了实现控件继承而增加的一些帮助方法,还有一些辅助类的方法,具体代码如下:

 

  1 $.extend(BUI,
  2   {
  3     /**
  4      * 将指定的方法或属性放到构造函数的原型链上,
  5      * 函数支持多于2个变量,后面的变量同s1一样将其成员复制到构造函数的原型链上。
  6      * @param  {Function} r  构造函数
  7      * @param  {Object} s1 将s1 的成员复制到构造函数的原型链上
  8      *            @example
  9      *            BUI.augment(class1,{
 10      *                method1: function(){
 11      *   
 12      *                }
 13      *            });
 14      */
 15     augment : function(r,s1){
 16       if(!$.isFunction(r))
 17       {
 18         return r;
 19       }
 20       for (var i = 1; i < arguments.length; i++) {
 21         BUI.mix(r.prototype,arguments[i].prototype || arguments[i]);
 22       };
 23       return r;
 24     },
 25     /**
 26      * 拷贝对象
 27      * @param  {Object} obj 要拷贝的对象
 28      * @return {Object} 拷贝生成的对象
 29      */
 30     cloneObject : function(obj){
 31             var result = $.isArray(obj) ? [] : {};
 32             
 33       return BUI.mix(true,result,obj);
 34     },
 35     /**
 36     * 抛出错误
 37     */
 38     error : function(msg){
 39         throw msg;
 40     },
 41     /**
 42      * 实现类的继承,通过父类生成子类
 43      * @param  {Function} subclass
 44      * @param  {Function} superclass 父类构造函数
 45      * @param  {Object} overrides  子类的属性或者方法
 46      * @return {Function} 返回的子类构造函数
 47          * 示例:
 48      *        @example
 49      *        //父类
 50      *        function base(){
 51      * 
 52      *        }
 53      *
 54      *        function sub(){
 55      * 
 56      *        }
 57      *        //子类
 58      *        BUI.extend(sub,base,{
 59      *            method : function(){
 60      *    
 61      *            }
 62      *        });
 63      *
 64      *        //或者
 65      *        var sub = BUI.extend(base,{});
 66      */
 67     extend : function(subclass,superclass,overrides, staticOverrides){
 68       //如果只提供父类构造函数,则自动生成子类构造函数
 69       if(!$.isFunction(superclass))
 70       {
 71         
 72         overrides = superclass;
 73         superclass = subclass;
 74         subclass =  function(){};
 75       }
 76 
 77       var create = Object.create ?
 78                         function (proto, c) {
 79                             return Object.create(proto, {
 80                                 constructor: {
 81                                     value: c
 82                                 }
 83                             });
 84                         } :
 85                         function (proto, c) {
 86                             function F() {
 87                             }
 88 
 89                             F.prototype = proto;
 90 
 91                             var o = new F();
 92                             o.constructor = c;
 93                             return o;
 94                         };
 95       var superObj = create(superclass.prototype,subclass);//new superclass(),//实例化父类作为子类的prototype
 96         //superObj1 = new superclass();//作为superclass属性
 97       subclass.prototype = BUI.mix(superObj,subclass.prototype);     //指定子类的prototype
 98       //superObj1.constructor = superclass;
 99       subclass.superclass = create(superclass.prototype,superclass);  
100       //subclass.prototype.constructor = subclass;
101       BUI.mix(superObj,overrides);
102       BUI.mix(subclass,staticOverrides);
103       return subclass;
104     },
105     /**
106      * 生成唯一的Id
107      * @method
108      * @param {String} prefix 前缀
109      * @default 'ks-guid'
110      * @return {String} 唯一的编号
111      */
112     guid : (function(){
113         var map = {};
114         return function(prefix){
115             prefix = prefix || BUI.prefix + GUID_DEFAULT;
116             if(!map[prefix]){
117                 map[prefix] = 1;
118             }else{
119                 map[prefix] += 1;
120             }
121             return prefix + map[prefix];
122         };
123     })(),
124     /**
125      * 判断是否是字符串
126      * @return {Boolean} 是否是字符串
127      */
128     isString : function(value){
129       return typeof value === 'string';
130     },
131     /**
132      * 判断是否数字,由于$.isNumberic方法会把 '123'认为数字
133      * @return {Boolean} 是否数字
134      */
135     isNumber : function(value){
136       return typeof value === 'number';
137     },
138     /**
139      * 控制台输出日志
140      * @param  {Object} obj 输出的数据
141      */
142     log : function(obj){
143       if(win.console && win.console.log){
144         win.console.log(obj);
145       }
146     },
147     /**
148     * 将多个对象的属性复制到一个新的对象
149     */
150     merge : function(){
151       var args = $.makeArray(arguments);
152       args.unshift({});
153       return $.extend.apply(null,args);
154 
155     },
156     /**
157      * 封装 jQuery.extend 方法,将多个对象的属性merge到第一个对象中
158      * @return {Object} 
159      */
160     mix : function(){
161       return $.extend.apply(null,arguments);
162     },
163     /**
164     * 创造顶层的命名空间,附加到window对象上,
165     * 包含namespace方法
166     */
167     app : function(name){
168       if(!window[name]){
169         window[name] = {
170           namespace :function(nsName){
171             return BUI.namespace(nsName,window[name]);
172           }
173         };
174       }
175       return window[name];
176     },
177     /**
178      * 将其他类作为mixin集成到指定类上面
179      * @param {Function} c 构造函数
180      * @param {Array} mixins 扩展类
181      * @param {Array} attrs 扩展的静态属性,默认为['ATTRS']
182      * @return {Function} 传入的构造函数
183      */
184     mixin : function(c,mixins,attrs){
185         attrs = attrs || [ATTRS];
186         var extensions = mixins;
187         if (extensions) {
188             c.mixins = extensions;
189 
190             var desc = {
191                 // ATTRS:
192                 // HTML_PARSER:
193             }, constructors = extensions['concat'](c);
194 
195             // [ex1,ex2],扩展类后面的优先,ex2 定义的覆盖 ex1 定义的
196             // 主类最优先
197             $.each(constructors, function (index,ext) {
198                 if (ext) {
199                     // 合并 ATTRS/HTML_PARSER 到主类
200                     $.each(attrs, function (i,K) {
201                         if (ext[K]) {
202                             desc[K] = desc[K] || {};
203                             // 不覆盖主类上的定义,因为继承层次上扩展类比主类层次高
204                             // 但是值是对象的话会深度合并
205                             // 注意:最好值是简单对象,自定义 new 出来的对象就会有问题(用 function return 出来)!
206                              BUI.mix(true,desc[K], ext[K]);
207                         }
208                     });
209                 }
210             });
211 
212             $.each(desc, function (k, v) {
213                 c[k] = v;
214             });
215 
216             var prototype = {};
217 
218             // 主类最优先
219             $.each(constructors, function (index,ext) {
220                 if (ext) {
221                     var proto = ext.prototype;
222                     // 合并功能代码到主类,不覆盖
223                     for (var p in proto) {
224                         // 不覆盖主类,但是主类的父类还是覆盖吧
225                         if (proto.hasOwnProperty(p)) {
226                             prototype[p] = proto[p];
227                         }
228                     }
229                 }
230             });
231 
232             $.each(prototype, function (k,v) {
233                 c.prototype[k] = v;
234             });
235         }
236         return c;
237     },
238     /**
239      * 生成命名空间
240      * @param  {String} name 命名空间的名称
241      * @param  {Object} baseNS 在已有的命名空间上创建命名空间,默认“BUI”
242      * @return {Object} 返回的命名空间对象
243      *        @example
244      *        BUI.namespace("Grid"); // BUI.Grid
245      */
246     namespace : function(name,baseNS){
247       baseNS = baseNS || BUI;
248       if(!name){
249         return baseNS;
250       }
251       var list = name.split('.'),
252         //firstNS = win[list[0]],
253         curNS = baseNS;
254       
255       for (var i = 0; i < list.length; i++) {
256         var nsName = list[i];
257         if(!curNS[nsName]){
258           curNS[nsName] = {};
259         }
260         curNS = curNS[nsName];
261       };    
262       return curNS;
263     },
264     prefix : 'ks-',
265     /**
266      * 替换字符串中的字段.
267      * @param {String} str 模版字符串
268      * @param {Object} o json data
269      * @param {RegExp} [regexp] 匹配字符串的正则表达式
270      */
271     substitute: function (str, o, regexp) {
272         if (!BUI.isString(str)
273             || !$.isPlainObject(o)) {
274             return str;
275         }
276 
277         return str.replace(regexp || /\\?\{([^{}]+)\}/g, function (match, name) {
278             if (match.charAt(0) === '\\') {
279                 return match.slice(1);
280             }
281             return (o[name] === undefined) ? '' : o[name];
282         });
283     },
284     /**
285      * 使第一个字母变成大写
286      * @param  {String} s 字符串
287      * @return {String} 首字母大写后的字符串
288      */
289     ucfirst : function(s){
290       s += '';
291             return s.charAt(0).toUpperCase() + s.substring(1);
292     },
293     /**
294      * 页面上的一点是否在用户的视图内
295      * @param {Object} offset 坐标,left,top
296      * @return {Boolean} 是否在视图内
297      */
298     isInView : function(offset){
299       var left = offset.left,
300         top = offset.top,
301         viewWidth = BUI.viewportWidth(),
302         wiewHeight = BUI.viewportHeight(),
303         scrollTop = BUI.scrollTop(),
304         scrollLeft = BUI.scrollLeft();
305       //判断横坐标
306       if(left < scrollLeft ||left > scrollLeft + viewWidth){
307         return false;
308       }
309       //判断纵坐标
310       if(top < scrollTop || top > scrollTop + wiewHeight){
311         return false;
312       }
313       return true;
314     },
315     /**
316      * 页面上的一点纵向坐标是否在用户的视图内
317      * @param {Object} top  纵坐标
318      * @return {Boolean} 是否在视图内
319      */
320     isInVerticalView : function(top){
321       var wiewHeight = BUI.viewportHeight(),
322         scrollTop = BUI.scrollTop();
323       
324       //判断纵坐标
325       if(top < scrollTop || top > scrollTop + wiewHeight){
326         return false;
327       }
328       return true;
329     },
330     /**
331      * 页面上的一点横向坐标是否在用户的视图内
332      * @param {Object} left 横坐标
333      * @return {Boolean} 是否在视图内
334      */
335     isInHorizontalView : function(left){
336       var viewWidth = BUI.viewportWidth(),     
337         scrollLeft = BUI.scrollLeft();
338       //判断横坐标
339       if(left < scrollLeft ||left > scrollLeft + viewWidth){
340         return false;
341       }
342       return true;
343     },
344     /**
345      * 获取窗口可视范围宽度
346      * @return {Number} 可视区宽度
347      */
348     viewportWidth : function(){
349         return $(window).width();
350     },
351     /**
352      * 获取窗口可视范围高度
353      * @return {Number} 可视区高度
354      */
355     viewportHeight:function(){
356          return $(window).height();
357     },
358     /**
359      * 滚动到窗口的left位置
360      */
361     scrollLeft : function(){
362         return $(window).scrollLeft();
363     },
364     /**
365      * 滚动到横向位置
366      */
367     scrollTop : function(){
368         return $(window).scrollTop();
369     },
370     /**
371      * 窗口宽度
372      * @return {Number} 窗口宽度
373      */
374     docWidth : function(){
375         var body = document.documentElement || document.body;
376         return $(body).width();
377     },
378     /**
379      * 窗口高度
380      * @return {Number} 窗口高度
381      */
382     docHeight : function(){
383         var body = document.documentElement || document.body;
384         return $(body).height();
385     }
386 

387   }); 

posted @ 2012-11-02 17:23  zaohe  阅读(1230)  评论(0编辑  收藏  举报