您当前的位置: 首页 >  jquery

第二章 jQuery技术解密 (四)

发布时间:2013-12-28 16:16:56 ,浏览量:0

2.3.4 生成 DOM 元素

jQuery.fn.init() 构造函数能够构建 jQuery 对象,并把匹配的 DOM 元素存储在 jQuery 对象内部集合中。jQuery.fn.init() 构造函数可以接收单个的 DOM 元素,也可以接收 DOM 集合。如果接收的是字符串型 ID 值,则直接在文档中查找对应的 DOM 元素,并把它传递给 jQuery 对象;如果接收的是字符串型 HTML 片段,则需要把这个字符串片段生成 DOM 元素。下面我们将重点分析 jQuery 是如何把 HTML 片段生成 DOM 元素的。

在2.3.3节中,我们可以看到 jQuery.fn.init() 构造器通过 jQuery.clean([match[1], context]); 语句实现把 HTML 片段生成 DOM 元素,jQuery.clean() 是一个公共函数。源代码及其注释如下所示。

jQuery.clean() 包含三个参数,其中 elems 和 context 可以支持多种形式的值。Elems 参数可以为数组、类数组、对象结构的形式。数组元素和对象属性可以混合使用。

对于数字类型参数,则会被转换为字符串型,除了字符串型外,其他的都放入返回的数组中,当然对于集合形式只需要读取集合中每个元素即可。

对于字符串型参数,则把它转换成 DOM 元素,再存入返回的数组中。转换的方式是,把 HTML 字符串片段赋值给创建的 div 元素的 innerHTML ,这样就可以把 HTML 字符串片段挂到 DOM 文档树中,从而实现把字符串转换成 DOM  元素。

在转换过程中,应该考虑 HTML 语法约定,因为标签嵌套是有严格限制的,例如,必须存在中。因此在执行转换前,还应该对 HTML 字符串进行预处理,即修正 HTML 标签不规范的用法,这也是 jQuery.clean() 函数的一个重要工作。

[html]  view plain copy
  1. <script type="text/javascript">  
  2. (function(){  
  3. var   
  4.     window = this,  
  5.     jQuery = window.jQuery = window.$ = function(selector, context){  
  6.         return new jQuery.fn.init(selector, context);  
  7.     },  
  8.     quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/;  
  9.   
  10. jQuery.fn = jQuery.prototype = {  
  11.     init: function(selector, context){  
  12.         selector = selector || document;  
  13.   
  14.         if(typeof selector == "string"){  
  15.             var match = quickExpr.exec(selector);  
  16.   
  17.             if (match && (match[1] || !context)){  
  18.                 // 第二种情况,处理 HTML 字符串,类似 $(html) -> $(array)  
  19.                 if (match[1]){                    
  20.                     selector = jQuery.clean( [ match[1] ], context );  
  21.                 }     
  22.             }  
  23.         }   
  24.     }  
  25. };  
  26. jQuery.fn.init.prototype = jQuery.fn;   
  27.   
  28. // jQuery 功能扩展函数  
  29. jQuery.extend = jQuery.fn.extend = function(obj){  
  30.     for(var prop in obj){  
  31.         this[prop] = obj[prop];  
  32.     }  
  33.     return this;  
  34. };  
  35. // 公共函数扩展  
  36. jQuery.extend({  
  37.     // 参数说明:object 表示 jQuery 对象,callback 表示回调函数, args 回调函数的参数数组  
  38.     each: function(object, callback, args){  
  39.         var name, i=0, length = object.length;  
  40.         if(args){     // 如果存在回调函数的参数数组  
  41.             if(length === undefined){ // 如果 object 不是 jQuery 对象  
  42.                 for(name in object){  // 遍历 object 的属性  
  43.                     if(callback.apply( object[name], args ) === false)  
  44.                                         // 在对象上调用回调函数  
  45.                         break;          // 如果回调函数返回值为 false ,则跳出循环  
  46.                 }  
  47.             } else {  
  48.                 for( ; i<length; )       // 遍历 jQuery 对象数组  
  49.                     if(callback.apply( object[i++], args ) === false)  
  50.                                         // 在对象上调用回调函数  
  51.                         break;          // 如果回调函数返回值为 false ,则跳出循环  
  52.             }  
  53.         } else {  
  54.             if(length === undefined){   // 如果 object 不是 jQuery 对象  
  55.                 for(name in object)     // 遍历 object 的属性  
  56.                     if(callback.call(object[name], name, object[name]) === false)  
  57.                         break;          // 如果回调函数返回值为 false ,则跳出循环    
  58.             } else {            // 如果 object 是 jQuery 对象  
  59.                 for(var value = object[0]; // 遍历 jQuery对象数组  
  60.                     i<length && callback.call(value, i, value) !== false; value = object[++i]){}  
  61.             }  
  62.         }  
  63.     },  
  64.     // 把HTML字符串片段转换成 DOM 元素  
  65.     // 参数说明:  
  66.     // elems 参数表示多个 HTML 字符串片段的数据  
  67.     // context 参数表示上下文  
  68.     // fragment 参数表示框架对象  
  69.     clean: function(elems, context, fragment){  
  70.         context = context || document; // 默认的上下文是 document  
  71.         // 在IE中 !context.createElement 是错误用法,因为它返回的是对象类型,而不是逻辑值,  
  72.         // 故通过返回类型进行判断        
  73.         if(typeof context.createElement == "undefined")  
  74.             // 支持 context 为 jQuery 对象,并获取第一个元素  
  75.             context = context.ownerDocument || context[0] && context[0].ownerDocument || document;  
  76.         // 如果仅匹配一个标签,且没有指定框架参数,则直接创建 DOM 元素,并跳过后面的解析  
  77.         if(!fragment && elems.length === 1 && typeof elems[0] === "string") {  
  78.             var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);  
  79.             if ( match )  
  80.                 return [ context.createElement( match[1] ) ];  
  81.         }  
  82.         var ret = [], scripts = [], div = context.createElement("div");  
  83.         // 匹配每一个 HTML 字符串片段,并为每一个片段执行回调函数             
  84.         jQuery.each(elems, function(i, elem){  
  85.             if(typeof elem === "number") // 把数值转换为字符串的高效方法  
  86.                 elem += '';  
  87.             if(!elem) // 如果不存在元素,则返回,或者为 ''、undefined、false 等时也返回  
  88.                 return;  
  89.             // HTML 字符串转换为 DOM 节点  
  90.             if(typeof elem === "string"){  
  91.                 // 统一转换为 XHTML 严谨型文档的标签形式,如 <div/> 的形式修改为 <div>
关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    108697博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0551s