jQuery构造函数init参数分析(三)
分析完了字符串情况剩下的就不多了。
5.参数selector是函数
这个就是很容易想到了,首先说一下dom加载。我们通常在head里面写脚本的时候需要等待文档加载在进行处理,js是这么写的
window.onload=function(){
your code...
}
但是这样是需要等待所有资源都加载完毕才会执行,如果页面有很多图片的话就会加载的很慢。dom2级呢有一个加载完成事件DOMContentLoad比较好用,这个事件是会在html文档结构加载完毕触发。比如说这个页面有10个img元素,只要获取到这些元素而不会在意是否图片被加载进来这样就很好地提高了js加载速度,用法如下:
addEventListener("DOMContentLoad", function () {
your code
}, false);
遗憾的是ie低版本浏览器并不支持这种写法,首先ie低版本没有addEventListener这个绑定事件的方法,倒是有一个相似方法addEvent但是由于存在很多问题往往不被使用,再者ie低版本没有DOMContentLoad事件。那么针对ie低版本(ie9一下)呢通常用doScroll结合onreadystatechange方法检测。具体可以参考http://www.iefans.net/ie-mofang-domcontentloaded/
说完了回到jQuery,我们使用jQuery时就不用考虑浏览器兼容问题了直接:
$(function(){
yourcode...
})
//或者
$(document).ready(function(){
yourcode...
})
第一种就是我们要讲的情况selector是一个函数,其实jQuery会调ready方法,源码如下:
// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
rootjQuery之前也已经说过啦就是$(document),最终还是执行的ready方法这就是为什么dom加载的两种写法都可以,关于readdy方法也是会用到之前分析的DOMContentLoad,doScroll,onreadystatechange等只不过会更复杂写以后学到dom加载模块在慢慢分析吧。 6.selector是jQuery对象或者特殊对象
这个种情况应该不多没有人喜欢这样$($(document))写吧,但是如果非要有人这样写jQuery也支持
if ( selector.selector !== undefined ) {
this.selector = selector.selector;
this.context = selector.context;
}
如果selector存在selector属性说明就可能是jquery对象,为什么说可能是呢,看下面的例子就明白了
console.log($({selector:1}));
当我这样写的时候是不是selector(此时是对象{selector:1})的selector属性存在啊而且最后也会生成结果
[Object, selector: 1, context: undefined, constructor: function, init: function, jquery: "1.7.1"…]
0: Object
context: undefined
length: 1
selector: 1
__proto__: jQuery[0]
这个是对原书作者的修正,并不是只有jQuery对象才在这里处理
如果前面说的所有情况都不符合那么jQuery还有最后一招
return jQuery.makeArray( selector, this );
makeArray方法将类数组对象转换为数组对象。但是在代码内部还有更艰巨的任务就是把一些数组、类数组普通对象等不是jQuery的形式的转换成jQuery形式。这个方法在以后详细分析。到了这里jQuery构造函数init的参数就分析完了大类有7个细分呢有12个分类。用原书一张图总结一下吧



下面是整个init函数1.7.1的源码
init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined)
if ( !selector ) {
return this;
}
// Handle $(DOMElement)
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
// The body element only exists once, optimize finding it
if ( selector === "body" && !context && document.body ) {
this.context = document;
this[0] = document.body;
this.selector = selector;
this.length = 1;
return this;
}
// Handle HTML strings
if ( typeof selector === "string" ) {
// Are we dealing with HTML string or an ID?
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];
} else {
match = quickExpr.exec( selector );
}
// Verify a match, and that no context was specified for #id
if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
doc = ( context ? context.ownerDocument || context : document );
// If a single string is passed in and it's a single tag
// just do a createElement and skip the rest
ret = rsingleTag.exec( selector );
if ( ret ) {
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
}
return jQuery.merge( this, selector );
// HANDLE: $("#id")
} else {
elem = document.getElementById( match[2] );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
// Otherwise, we inject the element directly into the jQuery object
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
// HANDLE: $(expr, $(...))
} else if ( !context || context.jquery ) {
return ( context || rootjQuery ).find( selector );
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor( context ).find( selector );
}
// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
if ( selector.selector !== undefined ) {
this.selector = selector.selector;
this.context = selector.context;
}
return jQuery.makeArray( selector, this );
},
jQuery构造函数init参数分析(三)的更多相关文章
- jQuery构造函数init参数分析(一)
在我的上一篇随笔里面分析了jQuery的构造函数,jQuery对象中有一个原型方法init才是是真正的构造函数,通过init的原型对象跟jQuery的原型对象保持引用关系使得init的实例可以正常调用 ...
- jQuery构造函数init参数分析(二)
接着上一篇随笔讨论. 如果selector是其他字符串情况就比较多了比较复杂了 // Handle HTML strings if ( typeof selector === "string ...
- 浅谈jQuery构造函数
$()函数到底做的什么 jQuery在前端领域路人皆知,对于一向喜欢玩js的博主来说,虽然能力有限,但是还是很喜欢研究他的做为.那么一个简单的美元符号$与一对常见的()括号,jQuery底层到底做了哪 ...
- jQuery学习笔记之jQuery.fn.init()的参数分析
这篇文章主要介绍了jQuery.fn.init()的参数分析,需要的朋友可以参考下 从return new jQuery.fn.init( selector, context, rootjQuer ...
- jQuery分析(3) - jQuery.fn.init
1.前言 上一篇jQuery分析(2)中了解了jQuery库的骨架实现原理,这就好比摇滚音乐,摇滚音乐不是某种音乐他就像一个音乐盒子,里面包含了各种不同的摇滚风格(山地.朋克.乡村.流行.硬摇.金属. ...
- jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)
在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...
- 四.jQuery源码解析之jQuery.fn.init()的参数解析
从return new jQuery.fn.init( selector, context, rootjQuery )中可以看出 参数selector和context是来自我们在调用jQuery方法时 ...
- Android中自定义样式与View的构造函数中的第三个参数defStyle的意义
零.序 一.自定义Style 二.在XML中为属性声明属性值 1. 在layout中定义属性 2. 设置Style 3. 通过Theme指定 三.在运行时获取属性值 1. View的第三个构造函数的第 ...
- jQuery构造函数分析
在我的上一篇文章里面 阐述了jQuery的大致框架,知道了所有代码都是写在了一个自调用匿名函数里面,并且传入了window对象,源码是这样的: (function( window, undefined ...
随机推荐
- java中异常注意的细节1
/* public class Test{ public static void main(String[] args){ int i=0; try{ func();//区别就是该函数抛出的异常被封装 ...
- 如何用分析函数找出EMP表中每个部门工资最高的员工
EMP表是Oracle测试账户SCOTT中的一张雇员表,首先,我们来看看emp表的数据 SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE ...
- Unity3D重要知识点
数据结构和算法很重要!图形学也很重要!大的游戏公司很看重个人基础,综合能力小公司看你实际工作能力,看你的Demo. 1.什么是渲染管道? 是指在显示器上为了显示出图像而经过的一系列必要操作. 渲染管道 ...
- How do annotations work internally--转
原文地址:http://stackoverflow.com/questions/18189980/how-do-annotations-work-internally The first main d ...
- php操作mongodb中的ISODate格式日期
mongodb 中数据记录的日期格式为"dateCreated" : ISODate("2011-12-20T07:22:50.836Z")经过翻阅php官网中 ...
- js断点调试心得
虽然网上已经有多的数不清的调试教程了,但仍然没有发现哪篇文章写的通俗易懂,索性自己尝试写写自己的一些使用习惯或者说是心得,希望对那些还不是很懂得使用断点调试的孩子有一些帮助(大神请无视~). 1.断点 ...
- 如何提升我的HTML&CSS技术,编写有结构的代码
前言 之前写了四篇HTML和CSS的知识点,也相当于是一个知识点汇总.有需要的可以收藏,平时开发过程中应该会遇到这些点,到时候再查看这些博客可能更容易理解.从这篇开始更多的介绍开发过程经常让人头痛的前 ...
- JS的toFixed方法设置小数点位数后再进行计算,数据出错问题
这个应该算作失真,或者也不算.情况就是用了toFixed后再进行相关计算,得不到预期的结果 具体看例子 比如想动态计算百分比,保留一位小数如94.4%这样子 var blobTo = 409600; ...
- jquery-easyui-tree异步树
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- C# 中反射获取某类的子类和根据类型名动态创建对象
有时候,为了快速批量处理已经实现某个基类或者某个接口的子类,需要通过反射的方式获取到他们的类类型(Type),然后再通过 1 Activator.CreateInstance(objType); 或者 ...