- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章jquery的总体架构分析及实现示例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
jQuery整体框架甚是复杂,也不易读懂,这几日一直在研究这个笨重而强大的框架。jQuery的总体架构可以分为:入口模块、底层模块和功能模块。这里,我们以jquery-1.7.1为例进行分析.
jquery的总体架构 。
。
。
分析一下以上代码,我们发现jquery采取了匿名函数自执行的写法,这样做的好处就是可以有效的防止命名空间与变量污染的问题。缩写一下以上代码就是:
。
。
参数window 。
匿名函数传了两个参数进来,一个是window,一个是undefined。我们知道,在js中变量是有作用域链的,这两个变量的传入就会变成匿名函数的局部变量,访问起来的时候速度会更快。通过传入window对象可以使window对象作为局部变量使用,那么,函数的参数也都变成了局部变量,当在jquery中访问window对象时,就不需要将作用域链退回到顶层作用域,从而可以更快的访问window对象.
参数undefined 。
js在查找变量的时候,js引擎首先会在函数自身的作用域中查找这个变量,如果没有的话就继续往上找,找到了就返回该变量,找不到就返回undefined。undefined是window对象的一个属性,通过传入undefined参数,但又不进行赋值,可以缩短查找undefined时的作用域链。在 自调用匿名函数 的作用域内,确保undefined是真的未定义。因为undefined能够被重写,赋予新的值.
jquery.fn是啥?
。
。
通过分析以上代码,我们发现jQuery.fn即是jQuery.prototype,这样写的好处就是更加简短吧。之后,我们又看到jquery为了简洁,干脆使用一个$符号来代替jquery使用,因此,在我们使用jquery框架的使用经常都会用到$(), 。
构造函数jQuery() 。
图片描述 。
jQuery的对象并不是通过 new jQuery 创建的,而是通过 new jQuery.fn.init 创建的:
。
var jQuery = function( selector, context ) { 。
。
return new jQuery.fn.init( selector, context, rootjQuery ),
} 。
。
这里定义了一个变量jQuery,他的值是jQuery构造函数,在955行(最上面的代码)返回并赋值给jQuery变量 。
jQuery.fn.init 。
jQuery.fn (上面97行)是构造函数jQuery()的原型对象,jQuery.fn.init()是jQuery原型方法,也可以称作构造函数。负责解析参数selector和context的类型并执行相应的查找.
参数context:可以不传入,或者传入jQuery对象,DOM元素,普通js对象之一 参数rootjQuery:包含了document对象的jQuery对象,用于document.getElementById()查找失败等情况.
。
。
默认情况下,对匹配元素的查找从根元素document 对象开始,即查找范围是整个文档树,不过也可以传入第二个参数context来限定它的查找范围。例如:
。
。
方法jQuery.extend(object)和jQuery.fn.extend(object)用于合并两个或多个对象到第一个对象。相关源代码如下(部分):
。
。
jQuery.extend(object); 为jQuery类添加添加类方法,可以理解为添加静态方法。如:
。
。
便为 jQuery 添加一个为add 的 “静态方法”,之后便可以在引入 jQuery 的地方,使用这个方法了, 。
$.add(3,4); //return 7 jQuery.fn.extend(object),查看一段官网的代码演示如下:
。
<label><input type="checkbox" name="foo"> Foo</label> <label><input type="checkbox" name="bar"> Bar</label> 。
。
<script> jQuery.fn.extend({ check: function() { return this.each(function() { this.checked = true; }); }, uncheck: function() { return this.each(function() { this.checked = false; }); } }); // Use the newly created .check() method $( "input[type='checkbox']" ).check(); </script> 。
。
CSS选择器引擎 Sizzle 。
可以说,jQuery是为操作DOM而诞生的,jQuery之所以如此强大,得益于CSS选择器引擎 Sizzle,解析规则引用网上的一段实例:
selector:"div > p + div.aaron input[type="checkbox"]" 。
解析规则: 1 按照从右到左 2 取出最后一个token 比如[type="checkbox"] { matches : Array[3] type : "ATTR" value : "[type=" checkbox "]" } 3 过滤类型 如果type是 > + ~ 空 四种关系选择器中的一种,则跳过,在继续过滤 4 直到匹配到为 ID,CLASS,TAG 中一种 , 因为这样才能通过浏览器的接口索取 5 此时seed种子合集中就有值了,这样把刷选的条件给缩的很小了 6 如果匹配的seed的合集有多个就需要进一步的过滤了,修正选择器 selector: "div > p + div.aaron [type="checkbox"]" 7 OK,跳到一下阶段的编译函数 。
deferred对象 。
开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的.
通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数.
但是,在回调函数方面,jQuery的功能非常弱。为了改变这一点,jQuery开发团队就设计了deferred对象.
简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行.
回顾一下jQuery的ajax操作的传统写法:
。
在上面的代码中,$.ajax()接受一个对象参数,这个对象包含两个方法:success方法指定操作成功后的回调函数,error方法指定操作失败后的回调函数.
。
$.ajax()操作完成后,如果使用的是低于1.5.0版本的jQuery,返回的是XHR对象,你没法进行链式操作;如果高于1.5.0版本,返回的是deferred对象,可以进行链式操作.
现在,新的写法是这样的:
。
为多个操作指定回调函数 。
。
deferred对象的另一大好处,就是它允许你为多个事件指定一个回调函数,这是传统写法做不到的.
请看下面的代码,它用到了一个新的方法$.when():
。
$.when($.ajax("test1.html"), $.ajax("test2.html")) 。
。
.done(function(){ alert("哈哈,成功了!"); }) 。
.fail(function(){ alert("出错啦!"); }),
。
这段代码的意思是,先执行两个操作$.ajax("test1.html")和$.ajax("test2.html"),如果都成功了,就运行done()指定的回调函数;如果有一个失败或都失败了,就执行fail()指定的回调函数.
jQuery.Deferred( func ) 的实现原理 。
内部维护了三个回调函数列表:成功回调函数列表、失败回调函数列表、消息回调函数列表,其他方法则围绕这三个列表进行操作和检测.
jQuery.Deferred( func ) 的源码结构:
。
jQuery.extend({ 。
。
Deferred: function( func ) { // 成功回调函数列表 var doneList = jQuery.Callbacks( "once memory" ), // 失败回调函数列表 failList = jQuery.Callbacks( "once memory" ), // 消息回调函数列表 progressList = jQuery.Callbacks( "memory" ), // 初始状态 state = "pending", // 异步队列的只读副本 promise = { // done, fail, progress // state, isResolved, isRejected // then, always // pipe // promise }, // 异步队列 deferred = promise.promise({}), key; // 添加触发成功、失败、消息回调函列表的方法 for ( key in lists ) { deferred[ key ] = lists[ key ].fire; deferred[ key + "With" ] = lists[ key ].fireWith; } // 添加设置状态的回调函数 deferred.done( function() { state = "resolved"; }, failList.disable, progressList.lock ) .fail( function() { state = "rejected"; }, doneList.disable, progressList.lock ); // 如果传入函数参数 func,则执行。 if ( func ) { func.call( deferred, deferred ); } 。
// 返回异步队列 deferred return deferred; }, } 。
。
jQuery.when( deferreds ) 。
提供了基于一个或多个对象的状态来执行回调函数的功能,通常是基于具有异步事件的异步队列.
jQuery.when( deferreds ) 的用法 。
如果传入多个异步队列对象,方法 jQuery.when() 返回一个新的主异步队列对象的只读副本,只读副本将跟踪所传入的异步队列的最终状态.
一旦所有异步队列都变为成功状态,“主“异步队列的成功回调函数被调用; 。
如果其中一个异步队列变为失败状态,主异步队列的失败回调函数被调用.
。
。
图片描述 。
异步队列 Deferred 。
解耦异步任务和回调函数 。
为 ajax 模块、队列模块、ready 事件提供基础功能.
原型属性和方法 。
原型属性和方法源代码:
。
。
属性selector用于记录jQuery查找和过滤DOM元素时的选择器表达式。 属性.length表示当前jquery对象中元素的个数。 方法.size()返回当前jquery对象中元素的个数,功能上等同于属性length,但应该优先使用length,因为他没有函数调用开销.
.size()源码如下:
。
。
方法.toArray()将当前jQuery对象转换为真正的数组,转换后的数组包含了所有元素,其源码如下:
。
。
方法.get(index)返回当前jQuery对象中指定位置的元素,或包含了全部元素的数组。其源 码如下:
。
get: function( num ) { return num == null ?
。
// Return a 'clean' array this.toArray()
// Return just the object ( num < 0 ? this[ this.length + num ] : this[ num ] ); }.
如果没有传入参数,则调用.toArray()返回了包含有锁元素的数组;如果指定了参数index,则返回一个单独的元素,index从0开始计数,并且支持负数.
。
首先会判断num是否小于0,如果小于0,则用length+num重新计算下标,然后使用数组访问操作符([])获取指定位置的元素,这是支持下标为负数的一个小技巧;如果大于等于0,直接返回指定位置的元素.
eg()和get()使用详解:jquery常用方法及使用示例汇总 。
方法.each()用于遍历当前jQuery对象,并在每个元素上执行回调函数。方法.each()内部通过简单的调用静态方法jQuery.each()实现:
。
。
回调函数是在当前元素为上下文的语境中触发的,即关键字this总是指向当前元素,在回调函数中return false 可以终止遍历.
方法.map()遍历当前jQuery对象,在每个元素上执行回调函数,并将回调函数的返回值放入一个新jQuery对象中。该方法常用于获取或设置DOM元素集合的值.
。
。
原型方法.pushStack()创建一个新的空jQuery对象,然后把DOM元素集合放入这个jQuery对象中,并保留对当前jQuery对象的引用.
原型方法.pushStack()是核心方法之一,它为以下方法提供支持:
jQuery对象遍历:.eq()、.first()、.last()、.slice()、.map().
DOM查找、过滤:.find()、.not()、.filter()、.closest()、.add()、.andSelf().
DOM遍历:.parent()、.parents()、.parentsUntil()、.next()、.prev()、.nextAll()、.prevAll()、.nextUnit()、.prevUnit()、.siblings()、.children()、.contents().
DOM插入:jQuery.before()、jQuery.after()、jQuery.replaceWith()、.append()、.prepent()、.before()、.after()、.replaceWith()。 定义方法.push( elems, name, selector ),它接受3个参数:
参数elems:将放入新jQuery对象的元素数组(或类数组对象).
参数name:产生元素数组elems的jQuery方法名.
参数selector:传给jQuery方法的参数,用于修正原型属性.selector。 方法.end()结束当前链条中最近的筛选操作,并将匹配元素还原为之前的状态 。
。
。
返回前一个jQuery对象,如果属性prevObect不存在,则构建一个空的jQuery对象返回。方法.pushStack()用于入栈,方法.end()用于出栈 。
静态属性和方法 。
相关源码如下:
。
。
未完待续、、、今天就先到这里了,下次补齐。别急哈小伙伴们 。
最后此篇关于jquery的总体架构分析及实现示例详解的文章就讲到这里了,如果你想了解更多关于jquery的总体架构分析及实现示例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!