ホームページ >ウェブフロントエンド >jsチュートリアル >jQuery の改良された詳細の紹介
jquery API」>jQuery 1.5 beta1 がリリースされました。学習とフォローアップという点では、今回は比較的遅いです (1.5 がいつアルファ版として公開されたのかさえわからないので、あくまでベータ版です)。このアップデートは AJAX を完全に書き直し、より強力なスケーラビリティを提供します。ただし、エネルギーとスペースの制限のため、新しい AJAX の分析は別の機会に譲ります。この記事では、
jQuery の詳細な改善点を簡単に紹介します。 ._Deferred と jQuery.Deferred
。jQuery.Deferred
は jQuery._Deferred
の拡張バージョンであるため、この問題については、jQuery._Deferred
から始めるとほとんどのことが説明できます。問題文字通り、私の最初の反応は「遅延ロード」であり、大文字の最初の文字は「タイプ」の定義であるはずなので、これはおそらく「遅延ロード機能を透過的に提供する」タイプです。これは多少の「遅延」を意味しますが、これは遅延読み込みの実装に使用されるものではありません
簡単に言うと、 jQuery._Deferred
は関数キューであり、その機能は次のとおりです。 : jQuery.Deferred
是jQuery._Deferred
的增强版,因此对于这个问题,从jQuery._Deferred
入手,就能说明一大半的问题。
什么是Deferred?从字面上看,我的第一反应是“延迟加载”,首字母大写的应该是“类型”的定义,所以这大概是一个“透明提供延迟加载功能”的类型吧。然而实际上,虽然确实带有那么一点点“延迟”的意思,这个东西却不是用来实现延迟加载的。
简单来说,jQuery._Deferred
是一个函数队列,他的作用有以下几点:
保存若干个函数。
在特定的时刻把保存着的函数全部执行掉。
执行过后,新进来的函数会立刻执行。
感觉是不是和啥东西很像?对,jQuery的ready函数就是这样的逻辑,实际中jQuery 1.5中的ready函数也确实被嫁接到这上面去了。
jQuery._Deferred
提供下面的接口:
done
:function(fn1, fn2, …)
的形式,用于把函数添加到队列中。
fire
:function(context, args)
的形式,使用context
指定this对象,args
指定参数,调用队列中所有函数。fire
被调用后,_Deferred会进入isResolved状态,未来对done
的调用不会再保存函数,而是直接调用函数。
resolve
:相当于调用fire(this, arguments)
,一个简化的方法。
isResolved
:用来判断_Deferred是否在isResolved状态,具体参考前面的fire
函数的解释。
cancel
:取消掉整个队列,这样不管未来是不是fire
,队列中的函数都不会再被调用。
说明白了jQuery._Deferred
,再来看看jQuery.Deferred
。这个东西其实就是2个_Deferred组成的,第一个称为deferred,用于保管“正常”状态下的函数;第二个称为failDeferred,用于保管“出错”状态下的函数。同时jQuery.Deferred
提供了一些新的接口:
then
:function(done, fail)
的形式,把done
添加进deferred
,把fail
添加进failedDeferred
。
fail
:相当于failDeferred
的done
函数。
fireReject
:相当于failDeferred
的fire
函数。
reject
:相当于failDeferred
的resolve
函数。
isRejected
:相当于failDeferred
的isResolved
函数。
同时jQuery.Deferred
取消了cancel
函数。
那么这个是啥用的呢?有“正常”和“出错”2个状态,同时又是异步的,很容易就能想到……对,给AJAX用的,在下一篇分析中再详细说明。
因为有了jQuery._Deferred
这个东西,jQuery.ready
函数变成依赖于函数队列,具体的变化有:
原来的readyList
变量已经不再是一个数组,而变成了jQuery._Deferred
对象。
原本在DOMContentLoaded时,调用readList
中所有函数的逻辑,现在也使用了jQuery._Deferred
中,原来的代码:
while ( (fn = ready[ i++ ]) ) { fn.call( document, jQuery ); }
变成了:
readyList.fire( document , [ jQuery ] );
新增了静态函数jQuery.parseXML
,用于提供浏览器兼容的从字符串转为XML文档的功能。
该函数的逻辑网上有很多,jQuery也没有特别的地方,大致分为以下2种:
对于标准浏览器,使用DOMParser
对象:
var parser = new DOMParser(); var xml = parser.parseFromString(text, 'text/html');
对于IE,使用Microsoft.XMLDOM
jQuery._Deferred
は次のインターフェイスを提供します: 🎜done
: の形式function(fn1, fn2, …)
はキューに関数を追加するために使用されます 🎜fire
: function の形式で。 (context, args)
、context
を使用してこの オブジェクトを指定し、args
を使用してパラメータを指定し、キュー内のすべての関数を呼び出します。 fire
が呼び出された後、_Deferred は isResolved 状態になり、その後の done
の呼び出しでは関数は保存されず、関数が直接呼び出されます。 🎜resolve
: 簡略化されたメソッドである fire(this, argument)
を呼び出すのと同じです。 🎜isResolved
: _Deferred が isResolved 状態であるかどうかを判断するために使用されます。詳細については、前の の説明を参照してください。 fire
関数。 🎜cancel
: キュー全体をキャンセルします。これにより、将来 fire
が発生するかどうかに関係なく、キュー内の関数はキャンセルされなくなります。再び呼ばれた。 🎜jQuery._Deferred
についてわかりやすく説明したので、jQuery.Deferred
を見てみましょう。これは実際には 2 つの _Deferred で構成されています。最初の _Deferred は deferred と呼ばれ、関数を「通常」の状態で保存するために使用されます。2 つ目の _Deferred は failDeferred と呼ばれます。関数を「エラー」ステータスに保存するために使用されます。同時に、jQuery.Deferred
はいくつかの新しいインターフェイスを提供します: 🎜then
: function (done 、fail)
、done
を deferred
に追加し、fail
を failedDeferred
に追加します。 🎜fail
: failDeferred
の done
関数と同等です。 🎜fireReject
: failDeferred
の fire
関数と同等です。 🎜reject
: failDeferred
の resolve
関数と同等です。 🎜isRejected
: failDeferred
の isResolved
関数と同等です。 🎜jQuery.Deferred
は cancel
関数をキャンセルします。 🎜🎜それで、これは何に使われるのでしょうか? 「正常」と「エラー」の 2 つの状態があり、同時に非同期であることは簡単に考えられます。はい、AJAX で使用されます。詳しくは次の分析で説明します。 🎜🎜jQuery.ready の変更点🎜🎜 jQuery._Deferred
により、jQuery.ready
関数は関数キューに依存するようになります。具体的な変更点は次のとおりです。元の readyList
変数は配列ではなくなり、jQuery._Deferred
オブジェクトになりました。 🎜🎜DOMContentLoaded のときに readList
内のすべての関数を呼び出す元のロジックは、jQuery._Deferred
でも使用されるようになりました。元のコード: 🎜 var parser = new ActiveXObject('Microsoft.XMLDOM'); parser.async = 'false'; parser.loadXML(text); var xml = parser.documentElement;🎜 🎜
expando = "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( //D/g, "" );🎜jQuery.parseXML 関数🎜🎜文字列をXMLドキュメントに変換します。 🎜🎜この関数のロジックはインターネット上に多数ありますが、jQuery には特別なロジックはありません。大まかに次の 2 つのタイプに分けられます。 🎜🎜 標準ブラウザの場合は、
DOMParser
オブジェクトを使用します。 $.each(['get', 'post'], function(i, method) { $[method] = function() { ... }; });🎜 IE の場合は、Microsoft.XMLDOM オブジェクトを使用します: 🎜
var parser = new ActiveXObject('Microsoft.XMLDOM'); parser.async = 'false'; parser.loadXML(text); var xml = parser.documentElement;
添加了jQuery.hasData
函数,用于判断一个元素是否有jQuery附加上去的数据。
修改了jQuery.expando
的实现,在原来单纯地取当前时间的基础上,添加了一个随机数:
expando = "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( //D/g, "" );
这样保证在同一时间,引入多个jQuery副本,这几个副本之间的expando不会相互冲突,导致元素上的data变得错乱。一般来说,是不会引入多个jQuery副本的,但是使用SealJS等的时候,配置不当的话,也是很容易出现此类问题的。
原本的hasClass
、addClass
、removeClass
函数都需要将元素的class属性分隔为数组,在1.4.4版本中,通过/n或/t进行分隔,在1.5中增加了一个/r,用于对应Windows平台下的换行符(/r/n)。
jQuery.fn.attr
函数,1.4.4版本中拒绝从TextNode和CommentNode上获取属性,在1.5版本中添加了一个AttributeNode(noteType == 2)。
在1.4.4版本中,jQuery会在页面unload的时候清理掉由jQuery维护的所有DOM事件,这是为了避免IE的内存泄露问题。但是在1.5中这一段代码不见了,不知是出于什么考虑。
对于IE下使用cloneNode
复制节点,会将事件也一起复制过来的问题,1.4.4中是采取复制innerHTML
的方式给予解决,而在1.5中则采纳了mootools团队提供的方法,使用cloneFixAttribute
函数修正该问题。
cloneFixAttribute
函数们于jQuery 1.5 beta1源码文件的5388-5438行,处理IE的BUG的原理很简单,当然前端里一些看似简单的东西,都是很难发现的:
IE中有个叫clearAttributes
的函数,会清除到节点上的所有属性,顺便把和事件相关的<a href="http://www.php.cn/wiki/1449.html" target="_blank">onclick</a>
之类的属性也去掉了。在复制出来的节点上调用这个函数,就会把属性清得干干净净。
IE中还有一个叫mergeAttributes
的函数,把一个节点的属性复制到另一个节点上,但他不会把和事件相关的属性复制过去。所以再把原始节点调用mergeAttributes
,把属性重新放回复制出来的节点上,这就相当于起到了去除事件相关属性的作用。
另外cloneFixAttribute
函数还处理了非常多IE6-8在cloneNode
上的兼容性问题,非常值得详细研究。
AJAX已经完全重写了,只留下一点边边角角保留着1.4.4版本的风采,这里只抽取一部分进行简单的说明。
原来版本中$.get
和$.post
的实现非常相似,具体来说仅有一个method配置项不同,因此在1.5版本中被合并起来了:
$.each(['get', 'post'], function(i, method) { $[method] = function() { ... }; });
ajaxSetup
函数现在加了一行return this;
,可以链式调用了。
serializeArray
函数现在统一将value中的换行符替换成Windows的风格(/r/n
)。
AJAX的回调函数中,作为参数的对象不再是原生的XMLHTTPRequest
,而是jQuery自己封装的称为jXHR的对象,这个对象提供了XMLHTTPRequest
的常用接口。
原本对于“请求成功”的浏览器状态码,除200-299以及304外,还有一个1223,来自于IE的一个BUG,会将204的状态码变成1223。现在因为有了jXHR对象,相当于中间多了一层,因此从jXHR对象获取statusCode
不会出现1223的情况,已经被变回204了。
jQuery.ajax
函数的配置项中多了一个statusCode
项,其结构为map,用于指定返回特定状态码时的回调函数,大致形式如下:
jQuery.ajax({ url: 'xxx', statusCode: { 200: function() { 处理请求成功 }, 404: function() { 处理页面未找到 }, 503: function() { 处理Service Unavailable } } });
再添加了这个回调后,jQuery.ajax
函数已经有非常多的回调函数,其触发过程如下:
根据返回的状态码,触发success
或者error
回调。
根据状态码,触发对应的statusCode回调。
触发complete
回调。
触发全局ajaxComplete
回调。
如果此时没有正在执行的AJAX,触发全局ajaxStop
回调。
入口函数jQuery.fn.init
现在多了一个参数,值始终为rootjQuery
,用于加速init
函数中对rootjQuery
变量的查找速度(减少了一层作用域):
// jQuery 1.5 beta1 源码23行 jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); }
jQuery对象支持继承了,具体的修改是将几处直接调用jQuery的代码改为了对this.constructor
的调用:
// 202行: return this.constructor( context ).find( selector ); // 253行: var ret = this.constructor(); // 334行: return this.prevObject || this.constructor(null);
同时还提供了jQuery.subclass
函数用于创建一个继承自jQuery的类型,由于不是很常用jQuery,更是从来没有用到过需要继承jQuery的情况,因此也不方便说这个功能的作用有多大。
以上がjQuery の改良された詳細の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。