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 ...
随机推荐
- ECharts+百度地图网络拓扑应用
前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图.ECharts和HT for Web三者结合起来 ...
- HT for Web 中Painter的介绍及用法
鉴于许多同学对Painter不熟悉,所以撰写此文介绍下.Painter的中文意思是画家.漆工,那放到HT里是什么意思呢?很简单,这是HT特有的一种接口,允许开发者在拓扑及其它通用组件上使用Canvas ...
- 浏览器桌面通知Notification探究
首先说明,这篇博文不是科普讲解的,而是立flag研究的,是关于浏览器消息自动推送,就是下面这个玩意: 最近常常在浏览器看到这样的消息推送,还有QQ.com的推送,现在我对这个不了解,不知道叫消息自动推 ...
- 歌词文件解析(二):LRC格式文件的绘制
通过对LRC文件的解析,可以轻松实现歌词可视化. 代码实现 函数名: paintLyrics(ByVal pBox As PictureBox, ByVal CurrentPosition As In ...
- 关于MVC中模型model的验证问题
今天在做项目练习的时候发现,MVC中使用自带的模型验证时会提前显示在界面上,比如下面所示: 这是什么原因了,是因为我在表示get请求的action里面返回了其界面所显示使用的model,我们知道mvc ...
- 初识ViewState
ViewState用法与Session相似 ViewState不能跨页面传递值,与session相反,不占用服务器空间. ViewState在刷新后会失效. 防止刷新使ViewState回初始值,可以 ...
- 【人在江湖飘,哪有不带刀】神器Jumony
大神博客:http://www.cnblogs.com/Ivony/p/3447536.html 项目地址:https://github.com/Ivony/Jumony 1.安装Jumony包 在N ...
- ASP.NET页面中去除VIEWSTATE视
保存页的所有视图状态信息和控件状态信息. 源码:http://www.jinhusns.com/Products/Download/?type=xcj 作者在早期参与的项目中曾遇到这样的需求:基于SE ...
- 示例 Edit 关闭键盘再显示
在某一些 Android 的机子上,点入 Edit 显示会键盘,但关闭键盘再点一次 Edit 后,键盘并不会再次显示出来. 实机测试: Sony Xperia ST17i:无法再次显示. Nexus ...
- Java中用户界面布局
绝对布局Absolute 通过放大或缩小界面的时候,组件大小和位置不会发生变化 浮动布局FlowLayout 调整应用程序窗口的大小时,组件将立刻重新排列 边界布局Border Layout 该位置有 ...