jQuery 源码解析(七) jQuery对象和DOM对象的互相转换
jQuery对象是一个类数组对象,它保存的是对应的DOM的引用,我们可以直接用[]获取某个索引内的DOM节点,也可以用get方法获取某个索引内的DOM节点,还可以用toArray()方法把jQuery对象一次性转换成一个数组,例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<script>
var jObject = $('p');
console.log(jObject[0].innerHTML) //输出:1
console.log(jObject[1].innerHTML) //输出:2
console.log(jObject.get(2).innerHTML) //输出:3
console.log(jObject.toArray()) //输出:Array(3) [ p, p, p ] ;每个元素都是一个DOM节点,等于对应的p元素
</script>
</body>
</html>
将DOM对象转换为jQuery对象就更方便了,直接放到jQuery的构造器内即可,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<script>
var p = document.getElementsByTagName('p'),
result = [];
for(let i = 0;i<p.length;i++) result.push(i) //getElementsByTagName获取的是HTMLCollection对象,也是个类数组,我们把它转换为数组格式 console.log( $(p) instanceof $ ) //输出true ;表示$(p)是一个jQuery对象
console.log( $(p).size() ) //输出:3 ;因为p内有3个DOM元素 console.log( $(p[0]) instanceof $ ) //输出true ;表示$(p)是一个jQuery对象
console.log( $(p[0]).size() ) //输出:1 ;因为我们只传入一个p[0],只有一个DOM节点
</script>
</body>
</html>
输出如下:
原因在代码里注释得挺详细了,嗯,就这样
源码分析
writer by:大沙漠 QQ:22969969
DOM转换成jQuery对象都是在jQuery内部的init()函数内实现的,如下:
init: function( selector, context, rootjQuery ) {
/*略*/
// Handle $(DOMElement)
if ( selector.nodeType ) { //selector有属性nodeType,则认为selector是DOM元素,例如:$(document.getELementById('d'))
this.context = this[0] = selector; //保存该DOM节点的引用
this.length = 1; //设置length属性为1
return this; //返回this,以支持链式操作
} /*略*/ return jQuery.makeArray( selector, this ); //这里是最后的逻辑,如果selector是数组或伪数组
},
makeArray是jQuery内部的一个函数,用于把一个类数组转换成真正的数据,如下:
makeArray: function( array, results ) { //将一个类数组对象转换为真正的数组
var ret = results || []; //如果results不存在则修正为空数组,初始化jQuery执行到这里时这里的result等于jQuery对象,也就是上面传进来的this if ( array != null ) { //过滤参数array是null、undefined的情况。
// The window, strings (and functions) also have 'length'
// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
var type = jQuery.type( array ); if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { //如果array没有属性length 或者 参数array是字符串,或者是函数,或者是正则,或者是Window对象
push.call( ret, array ); //认为参数array不是数组,也不是类数组对象,调用数组方法push()把该参数插入返回值ret的末尾。
} else {
jQuery.merge( ret, array ); //否则认为参数array是数组或类数组对象,调用方法jQuery.merge()把该参数合并到返回值ret中
}
} return ret;
},
最后返回该数组,因为我们在第二个参数传递了this,因此makeArray最后会返回this
对于jQuery对象转换为DOM对象来说,由于jQuery本身就是个类数组对象,因此,我们可以直接用[]获取索引,对于get和toArray方法来说,这些操作定义在jQuery的原型上,也就是jQuery.fn上的,如下:
jQuery.fn = jQuery.prototype = { //重写jQueyr.fn
/*略*/
toArray: function() { //将当前jQuery对象转换为真正的数组,转换后的数组包含了所有元素。
return slice.call( this, 0 );
},
get: function( num ) { //返回当前jQuery 对象中指定位置的元素或包含了全部元素的数组,
return num == null ? // Return a 'clean' array
this.toArray() : // Return just the object
( num < 0 ? this[ this.length + num ] : this[ num ] ); //直接返回this[num],也就是和我们用[]是一样的,只是封装了一下
},
/*略*/
}
我们可以看到对于get来说,就是直接从this[]上获取的,而toArray则调用了数组了slice方法,将类数组转换成真实的数组
jQuery 源码解析(七) jQuery对象和DOM对象的互相转换的更多相关文章
- jquery源码解析:jQuery静态属性对象support详解
jQuery.support是用功能检测的方法来检测浏览器是否支持某些功能.针对jQuery内部使用. 我们先来看一些源码: jQuery.support = (function( support ) ...
- 三.jQuery源码解析之jQuery的框架图
这张图片是对jQuery源码截图,一点一点拼出来的. 现在根据这张图片来对jQuery框架做一些说明. 一.16~9404行可以发现,最外层是一个自调用函数.当jQuery初始化时,这个自调用函数包含 ...
- jquery源码解析:jQuery数据缓存机制详解2
上一课主要讲了jQuery中的缓存机制Data构造方法的源码解析,这一课主要讲jQuery是如何利用Data对象实现有关缓存机制的静态方法和实例方法的.我们接下来,来看这几个静态方法和实例方法的源码解 ...
- jquery源码解析:jQuery数据缓存机制详解1
jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等 ...
- jquery源码解析:jQuery工具方法when详解
我们先来看when方法是如何使用的: var cb = $.when(); //when方法也是返回一个延迟对象,源码是return deferred.promise();返回的延迟对象不能修改状 ...
- jquery源码解析:jQuery工具方法Callbacks详解
我们首先来讲下Callbacks是如何使用的:第一个例子 function a(){} function b(){} var cb = $.Callbacks(); cb.add(a); cb.add ...
- jquery源码解析:jQuery队列操作queue方法实现的原理
我们先来看一下jQuery中有关队列操作的方法集: 从上图可以看出,既有静态方法,又有实例方法.queue方法,相当于数组中的push操作.dequeue相当于数组的shift操作.举个例子: fun ...
- jquery源码解析:val方法和valHooks对象详解
这一课,我们将讲解val方法,以及对value属性的兼容性处理,jQuery中通过valHooks对象来处理. 首先,我们先来看下val方法的使用: $("#input1").va ...
- jquery源码解析:jQuery延迟对象Deferred(工具方法)详解2
请接着上一课继续看. $.Deferred()方法中,有两个对象,一个是deferred对象,一个是promise对象. promise对象有以下几个方法:state,always,then,prom ...
随机推荐
- Linux中Swap与Memory内存简单介绍
1.背景介绍 这篇文章介绍一下Linux中swap与memory.对于memory没什么可说的就是机器的物理内存,读写速度低于cpu一个量级,但是高于磁盘不止一个量级.所以,程序和数据如果在内存的 ...
- mysql中的ifnull()函数判断空值
我们知道,在不同的数据库引擎中,内置函数的实现.命名都是存在差异的,如果经常切换使用这几个数据库引擎的话,很容易会将这些函数弄混淆. 比如说判断空值的函数,在Oracle中是NVL()函数.NVL2( ...
- node.js中this指向失效解决
问题:在外部单独使用类实例对象的方法,this没有指向该类实例对象 代码如下 class CQH { hello() { let name = this.name(); console.log(`He ...
- Spring Boot配置过滤器的两种方式
过滤器(Filter)是Servlet中常用的技术,可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,常用的场景有登录校验.权限控制.敏感词过滤等,下面介绍下Spring Boot配置过 ...
- Core源码(四)IEnumerable
首先我们去core的源码中去找IEnumerable发现并没有,如下 Core中应该是直接使用.net中对IEnumerable的定义 自己实现迭代器 迭代器是通过IEnumerable和IEnume ...
- crm-2
1.分页 web必备的功能 1)批量制造测试数据 定义一个空列表用于存储 orm对象 ,models.表名(字段=...)创建orm对象append到列表 ,使用bulk_create(对象列表)一次 ...
- JS基础语法---分支语句之:switch-case语句---3个练习
switch-case语句---分支语句---多分支语句 语法: switch(表达式){ case 值1:代码1;break; case 值2:代码2;break; case 值3:代码3;brea ...
- 利用InsertStatusValueRequest消息为新增的statuscode设定指定值(Value)
我是微软Dynamcis 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...
- js对象比较
使用闭包实现 js 对象按指定属性进行大小比较 需要比较的对象 let obj1 = { name:'张三', age:19 }; let obj2 = { name:'李四', age:22 }; ...
- [日常] 跨语言的POST请求问题的解决
部门对外提供了一个HTTP的POST接口,但是对方公司的程序员使用C语言进行的调用,PHP这边一直无法获取到参数.遇到这种情况是因为对方没有完全按照HTTP协议中的POST发送数据.在HTTP头部分没 ...