著者: nuysoft/Gao Yun QQ: 47214707 メール: nuysoft@gmail.com
声明: この記事はオリジナルの記事です。転載する必要がある場合は、出典を明記し、元のリンクを保持してください。
読んで、読んで、書いて、何か間違っていることがあれば教えてください。この章が終了したら、この章の PDF を公開します。
jQuery ソースコード解析シリーズのディレクトリについては、http://nuysoft.iteye.com/blog/1177451 を参照してください。体系的に書きたい場合は、興味のある部分から始めます。どのモジュールに興味がありますか。分析を優先することをお勧めする場合は、教えてください。一緒に勉強できます。
3.4 その他の静的ツール関数
// ユーティリティ関数を拡張します
jQuery.extend({
// $
の jQuery コントロールを解放します// 多くの JavaScript ライブラリは $ を関数名または変数名として使用しますが、jQuery も同様です.
// jQuery では、$ は単なる jQuery のエイリアスであるため、$ を使用しなくてもすべての機能が保証されます。
// jQuery 以外の別の JavaScript ライブラリを使用する必要がある場合は、それを呼び出すことができます。 noConflict() はライブラリに制御を返します。
// このメソッドにパラメータ true を渡すことで、$ と jQuery の両方の制御を別の JavaScript ライブラリに返すことができます。 // $
if ( window.$ === jQuery ) {
window.$ = _$;
}
// jQuery コントロールを渡す
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
},
// DOM を true に設定しますか?
isReady: false,
//ready イベントが発生する前に待機するアイテムの数を追跡するカウンター。#6781 を参照
// 追跡に使用されるカウンター。準備完了イベントがトリガーされるまで待機する回数
readyWait: 1,
// 準備完了イベントを保持 (または解放)
// 待機し続けるか、トリガー
holdReady : function(hold ) {
if (hold ) {
jQuery.readyWait ;
} else {
jQuery.ready( true );
/ / DOM の準備ができています
// ドキュメントがロードされたときの処理
ready: function( wait ) {
// 保留が解除されたか、DOMready/load イベントが発生し、まだ準備ができていません
//
if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
// 少なくとも IE が取得した場合に備えて本文が存在することを確認してください少し熱心すぎる (チケット #5443)。
// document.body が存在することを確認します。
if ( !document.body ) {
return setTimeout( jQuery.ready, 1 ) // DOM の準備ができていることを思い出してください
jQuery.isReady = true
// 通常の DOM Ready イベントが発生した場合、デクリメントし、必要に応じて待機します。
if ( wait !== true && - -jQuery.readyWait > 0 ) {
return;
}
// バインドされた関数がある場合は、
readyList.resolveWith( document, [ jQuery ] ); /バインドされた Ready イベントをトリガーします。
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger( "ready" ).unbind( "ready" );
}
}
},
//readyList イベント処理関数 queue を初期化します
// 異なるブラウザ間のバインディング イベントの違いと互換性があります
bindReady: function() {
if (readyList ) {
return ;
}
readyList = jQuery._Deferred();
//
// ブラウザ イベントがすでに発生した後に $(document).ready() が呼び出されるケースをキャッチします。 if ( document.readyState === "complete" ) {
// スクリプトが準備完了を遅らせる機会を許可するために、非同期的に処理します。
return setTimeout(
}
/ / Mozilla、Opera、および webkit nightlies は現在、このイベントをサポートしています
// ブラウザをスニッフィングする代わりにブラウザの機能を検出することにより、互換性のあるイベント
if ( document.addEventListener ) {
// 便利なイベント コールバックを使用します
// 高速な読み込みイベントを使用します
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// window.onload へのフォールバック。常に機能します
/ / ウィンドウを登録します。 onload コールバック関数
window.addEventListener( "load", jQuery.ready, false );
// IE イベント モデルが使用されている場合
} else if ( document.attachEvent ) {
// ensure onload の前に起動します。
// 遅いかもしれませんが、iframe にとっても安全です
// onreadystatechange が onload の前にトリガーされることを確認します。これは遅いかもしれませんが、iframe にとっては安全です
document.attachEvent( "onreadystatechange" , DOMContentLoaded );
// window.onload へのフォールバック。常に機能します
// window.onload コールバック関数を登録します
window.attachEvent( "onload", jQuery.ready )
// IE の場合フレームではありません
//ドキュメントの準備ができているかどうかを継続的に確認します
var toplevel = false;
try {
toplevel = window.frameElement == null;
} ) {}
if ( document.documentElement.doScroll && toplevel ) {
doScrollCheck();
}
}
},
// test/unit /core.js を参照isFunction の詳細については、
// バージョン 1.3 以降、alert
// のような DOM メソッドと関数はサポートされていません。
// Function
かどうか。 isFunction: function( obj) {
return jQuery.type(obj) === "function";
},
// 配列かどうか
// ブラウザが構築した場合in Array.isArray を実装するには、ブラウザ独自の実装を使用します。
// それ以外の場合は、オブジェクトを String に変換して、それが "[object Array]" であるかどうかを確認します。
isArray: Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
},
// オブジェクトかどうかを判断する大雑把な方法ウィンドウであるかどうか
// ウィンドウオブジェクトかどうかの簡易判定(setInterval属性の判定)
isWindow: function( obj ) {
return obj && typeof obj === "object" && "setInterval" in obj ;
},
// 予約語かどうか NaN
isNaN: function( obj ) {
// null に等しいか数値ではないか、または window.isNaN を呼び出して判断します
return obj == null || isNaN( obj );
type: function( obj ); / コア API を通じてオブジェクトを作成します。新しいキーワードは必要ありません
// 通常の関数は機能しません
// Object.prototype.toString メソッドを呼び出して、「[object Xxx]」形式の文字列を生成します
// class2type[ "[object " name "]" ] = name.toLowerCase();
return obj == null ?
String( obj ) :
class2type[ toString.call(obj) ) ] || "object";
} ,
// obj が純粋なオブジェクト (「{}」または「新しいオブジェクト」によって作成されたオブジェクト) かどうかを確認します
// console.info( $. isPlainObject( {} ) ); // true
// console.info( $.isPlainObject( '' ) ); // false
// console.info( $.isPlainObject( document.location ) ); // true
// console.info( $.isPlainObject( document ) ); // false
// console.info( $.isPlainObject( new Date() ) ); / console.info( $.isPlainObject( ) ); // false
// isPlainObject の分析と再構築 http://www.jb51.net/article/25047.htm
// jQuery.isPlainObject() についてhttp://www.cnblogs .com/phpmix/articles/1733599.html
isPlainObject: function( obj ) {
// オブジェクトである必要があります。
// IE のため、次のことも必要です。コンストラクター プロパティの存在を確認してください。
// DOM ノードとウィンドウ オブジェクトも通過しないようにしてください。
// オブジェクトである必要があります。
// 不正なポインター例外が発生するためです。 IE8 でスローされる場合、コンストラクターをチェックする必要があります。 属性
//DOM ノードおよびウィンドウ オブジェクト、false を返します
// obj が存在しないか、非オブジェクト型、DOM ノードまたはウィドナウ オブジェクトである場合、直接 false を返します
// 次の 3 つの考えられる状況をテストします:
// jQuery.type(obj) !== "object" タイプはオブジェクトではないので無視します
// obj.nodeType は DOM ノードがオブジェクトではないと考えますpure object
// jQuery.isWindow(obj) は、ウィンドウが純粋なオブジェクトではないと考えます Object
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
// 独自のコンストラクター プロパティは Object でなければなりません
// コンストラクター プロパティをテストします
// コンストラクター関数コンストラクターがあります。しかし、それは独自のプロパティではありません (つまり、プロトタイプを介して継承されます)、
if ( obj.constructor &&
!hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj. constructor.prototype, "isPrototypeOf") ) {
return false;
}
// 高速化するために、最初に独自のプロパティが列挙されます。
// 最後のプロパティが独自の場合、すべてのプロパティが列挙されます。
var key;
for ( key in obj ) {}
// key === 未定義で、単純な純粋なオブジェクトとみなされます
// hasOwn .call( obj, key ) 属性キーは空ではなく、属性キーのオブジェクトは独自のものです (つまり、プロトタイプを介して継承されていません)
return key === unknown || hasOwn.call( obj, key );
},
// オブジェクトが空かどうか
isEmptyObject: function( obj ) {
for ( var name in obj ) {
return false; }
return true;
},
// 例外をスローします
error: function( msg ) {
throw
},
// JSON を解析します
// parseJSON は文字列を JSON オブジェクトに変換します。
// 通常は eval を使用します。 parseJSON はこの操作をカプセル化しますが、eval は最後の手段として使用されます。
// JSON シリアル化 API と逆シリアル化 API が最新の JavaScript 標準に追加されたためです。
// ブラウザーがこの標準をサポートしている場合、これら 2 つの API はネイティブ コードを使用して JS エンジンに実装され、効率は明らかに eval よりもはるかに高くなります。
// 現在、Chrome と Firefox4 の両方がこの API をサポートしています。
parseJSON: function( data ) {
if ( typeof data !== "string" || !data ) {
return null;
}
// 先頭/末尾の空白を確認してくださいは削除されます (IE は処理できません)
data = jQuery.trim( data );
// 最初にネイティブ JSON パーサーを使用して解析を試みます
// ネイティブ JSON API。逆シリアル化は JSON.stringify(object)
if ( window.JSON && window.JSON.parse ) {
return window.JSON.parse( data );
}
// 受信したメッセージがデータは実際の JSON
// http://json.org/json2.js から借用したロジック
// ... 文字列の妥当性を大まかにチェックします
if ( rvalidchars.test( data.replace( rvalidescape , "@" )
.replace( rvalidtokens, "]" )
.replace( rvalidbraces, "")) ) {
return (new Function( "return " data )) }
jQuery.error( "無効な JSON: " data );
},
// クロスブラウザー XML 解析
// (xml と tmp は内部で使用されます)
// 解析XML クロスブラウザ
// parseXML 関数も主に標準 API と IE のパッケージです。
//標準 API は DOMParser オブジェクトです。
// IE は Microsoft.XMLDOM の ActiveXObject オブジェクトを使用します。
parseXML: function( data , xml , tmp ) {
if ( window.DOMParser ) { // 標準の標準 XML パーサー
tmp = new DOMParser()
xml = tmp.parseFromString( data) , "text/xml" );
} else { // IE IE の XML パーサー
xml = new ActiveXObject( "Microsoft.XMLDOM" );
xml.async = "false"; .loadXML( data );
}
tmp = xml.documentElement;
if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
jQuery. error( "無効な XML: " data );
}
return
},
// 操作なし function
noop: function() {},
//グローバル コンテキストでスクリプトを評価します
// Jim Driscoll による調査結果に基づく回避策
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval- javascript- global-context
// globalEval 関数は、スクリプトをグローバル コンテキスト (ウィンドウ) にロードします。
// window.execScript は IE で使用できます。
// 他のブラウザでは eval を使用する必要があります。
// jQuery コード全体が匿名関数であるため、現在のコンテキストは jQuery です。コンテキストを window に設定したい場合は、globalEval を使用する必要があります。
globalEval: function( data ) {
// データは空ではありません
if ( data && rnotwhite.test( data ) ) {
// Internet Explorer では execScript を使用します
//匿名関数を使用して、コンテキストが Firefox の jQuery ではなく window
// になるようにします
( window.execScript || function( data ) {
window[ "eval" ].call( window, data ) ;
} )( data );
}
},
// ノード名が同じかどうかを判断します
nodeName: function( elem, name ) {
// 無視しますcase
return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
},
// args は内部使用のみです
// オブジェクトまたは配列をスキャンします
each: function( object, callback, args ) {
var name, i = 0,
length = object.length,
isObj = length === unknown || jQuery.isFunction( object );
// パラメーター args がある場合は apply を呼び出し、コンテキストは現在トラバースされているオブジェクトに設定され、パラメーターは args です。
if ( args ) {
if ( isObj ) {
for ( name in object ) {
if ( callback.apply( object[ name ], args ) === false ) {
break;
}
}
} else {
for ( ; i < length; ) {
if ( callback.apply( object[ i ], args ) === false ) {
break;
}
}
}
// それぞれの最も一般的な使用のための特別な、高速なケース
// パラメーター引数がない場合、 call が呼び出され、コンテキストは現在トラバースされているオブジェクトに設定され、パラメーターは key に設定されます/index と値
} else {
if ( isObj ) {
for ( object 内の名前 ) {
if ( callback.call( object[ name ], name, object[ name ] ) = == false ) {
break;
}
}
} else {
for ( ; i < length; ) {
if ( callback.call( object[ i ] , i, object[ i ] ) === false ) {
break;
}
}
}
戻りオブジェクト;
/ / 可能な限りネイティブの String.trim 関数を使用します
// 可能な限りローカルの String.trim メソッドを使用します。それ以外の場合は、最初に先頭のスペースをフィルタリングし、次に末尾のスペースをフィルタリングします
trim:trim
function ? ( text ) {
return text == null ?
"" :
trim.call( text );
} :
// それ以外の場合は、独自のトリミング機能を使用します
function( text ) {
return text == null ?
"" :
text.toString().replace(trimLeft, "" ).replace(trimRight, "" ); >// 結果は内部使用のみです
// 擬似配列を配列に変換します
makeArray: function( array, results ) {
var ret = results || if ( array ! = null ) {
// ウィンドウ、文字列 (および関数) にも「長さ」があります
// 追加の typeof 関数チェックはクラッシュを防ぐためのものです
// Safari 2 (参照: #3039)
// Blackberry 4.7 RegExp の問題 #6930 を処理するためにロジックを若干調整しました
// 多くのブラウザ互換性テスト、非常に苦痛
var type = jQuery.type( array );
// テスト:長さ属性、文字列、関数はありますか? 通常の
// は配列ではなく、疑似配列でもありません
if ( array.length == null
|| type === "string"
|| タイプ === "関数"
|| jQuery.isWindow( array ) ) {
push.call( ret, array ); 🎜>} else {
// $.type ( $('div') ) // オブジェクト
jQuery.merge( ret, array );
}
}
return ret;
},
//
inArray: function( elem, array ) {
// ローカライズされた Array.prototype.indexOf はありますか
if (indexOf ) {
// 直接call Array.prototype.indexOf
return indexOf. call(array, elem);
}
// 配列を走査し、完全に等しい要素があるかどうかを確認し、添え字を返します
// for ループ: array.length を length 変数に格納すると、スコープを 1 つ減らすことができます。 search
for ( var i = 0, length = array.length; i if ( array[ i ] === elem ) {
return i;
}
}
// -1 が返された場合、それは配列内にないことを意味します
return
},
// 配列 2 番目を配列 1 番目にマージします。
merge: function( first, Second ) {
var i = first.length, //
j = 0; Second の長さ属性は Number 型であり、Second を配列として扱います。 j ) {
first[ i ] = Second[ j ] ;
}
} else {
// 2 番目をトラバースし、未定義の値を最初に追加します
while ( Second[ j] !== 未定義 ) {
first[ i ] = Second[ j ];
}
}
// first は実数の配列ではない可能性があるため、first の長さ属性を修正します。 🎜>first.length = i;
return first;
},
// コールバックが true を返した場合のみ保持されます。コールバックが false を返す場合
grep: function( elems, callback, inv ) {
var ret = [], retVal;
inv = !!inv>// 保存のみを実行します。項目
// バリデーター関数を渡す
// 配列を走査し、渡す項目のみを保存します 関数コールバックの要素を検証します
for ( var i = 0, length = elems.length; i < length; i ) {
// ここでのコールバックのパラメータ リストは、各
retVal = !!callback( elems[ i ], i ) と一致します。 ;
// 選択を反転するかどうか
if ( inv !== retVal ) {
ret.push( elems[ i ] ) ;
}
}
return ret;
},
// arg は内部使用のみです
// 配列またはオブジェクト elems の要素/属性を新しい配列に変換します
map: function( elems, callback, arg ) {
var value, key, ret = [],
i = 0,
length = elems.length,
// jquery オブジェクトは配列として扱われます
// elems が (疑似) 配列であるかどうかを検出します
// 1. jQuery オブジェクトを配列として扱います
// 2. length 属性が存在するかどうか、length が 0 に等しいかどうか、または最初と最後の要素が存在するかどうかを確認するか、jQuery.isArray が true を返すかどうかを確認します
isArray = jQuery の elems インスタンス
|| 長さ !== 未定義 && 長さのタイプ === "数値"
&& ( ( 長さ > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
// 配列かオブジェクトの違いであり、それ以外に違いはありません
//配列、各項目を
に変換します// 配列を走査し、各要素でコールバックを呼び出し、null ではない戻り値を ret に格納します
if ( isArray ) {
for ( ; i < length; i ) {
// パラメータは value、index、arg の順に実行します。
value = callback( elems[ i ], i, arg ); // null の場合返される、無視します (戻り値はありません。値関数は未定義を返します)
if ( value != null ) {
ret[ ret.length ] = value;
}
}
// Go object のすべてのキーを介して、
// オブジェクトを走査し、各属性のコールバックを呼び出し、null ではない戻り値を ret
} に格納します else {
for ( key in elems ) {
// コールバックを実行します。パラメータは、value、key、arg の順です。
value = callback( elems[ key ], key, arg )
// 上記と同じ
if ( value != null ) {
ret[ ret .length ] = value;
}
}
}
// ネストされた配列を平坦化します
// ネストされた配列を平坦化します
// concat:
// 項目が配列の場合、その内容を末尾に追加します。
// 項目が配列でない場合は、単一の配列要素として配列の末尾に追加します。
return ret.concat.apply( [], ret );
},
// オブジェクトのグローバル GUID カウンター
guid: 1,
// 関数をコンテキストにバインドします、オプションで部分的に
// 引数を適用します。
// プロキシ メソッド: fn のコンテキストを指定します (つまり、this)
// jQuery.proxy( function, context)
// jQuery.proxy( context, name )
proxy: function( fn, context ) {
// context が文字列の場合、コンテキストを fn に設定し、fn は fn[ context ]
// つまり、 fn の context メソッド コンテキストは fn です (これはデフォルトではありませんか?TODO)
if ( typeof context === "string" ) {
var tmp = fn[ context ];
fn = tmp; / ターゲットが呼び出し可能かどうかを判断するためのクイック チェック。仕様内では
// これは TypeError をスローしますが、未定義を返すだけです。
// ターゲットが呼び出し可能かどうかを判断するためのクイック チェックは、仕様内で行います。 、TypeError がスローされます。
// ただし、ここでは unknown のみが返されます
if ( !jQuery.isFunction( fn ) ) {
return
}
// シミュレートされたバインド
var args = slide.call( argument, 2 ), // パラメーター リストから fn,context を削除します
proxy = function() {
// コンテキストを context とパラメーターに設定します
return fn .apply ( context, args.concat(lice.call(arguments ) ) );
}
// 削除できるように、固有のハンドラーの guid を元のハンドラーと同じに設定します
/ / 統合プロキシを削除できるようにするための guid
proxy.guid = fn.guid || jQuery.guid ;
return proxy;
/ / 多機能メソッド値を取得してコレクションに設定します
// 関数の場合、値はオプションで実行できます
// 多機能関数。値が関数である場合、コレクションの属性値を読み取りまたは設定します。
// fn: jQuery.fn.css, jQuery.fn.attr, jQuery.fn.prop
access: function( elems, key, value, exec, fn, pass ) { var length = elems.length;
// 多くの属性を設定する
// 複数の属性がある場合は、
if ( typeof key === "object" ) {
for ( var k in key ) {
jQuery.access( elems, k, key[k], exec, fn, value );
}
return elems;
}
// 1 つの属性を設定します
// プロパティを 1 つだけ設定します
if ( value !== unknown ) {
// オプションで、 exec が true の場合に関数の値が実行されます
exec = !pass && exec && jQuery.isFunction ( value);
for ( var i = 0; i fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems) [ i], key ) ) : value, pass );
}
return elems;
}
// 属性の読み取り
return length ? elems[0], key ) : unknown;
},
// 現在時刻を取得する便利な関数
now: function() {
return (new Date()).getTime() ;
},
// jQuery.browser の使用は推奨されません。
// 詳細: http://docs.jquery.com/Utilities/jQuery.browser
//非推奨の jQuery.browser、jQuery.support の使用をお勧めします。
// Navigator 使用されているブラウザに関する情報
// Navigator.userAgent によって使用されるユーザー エージェント ヘッダーの値を宣言する読み取り専用の文字列。 HTTP リクエストのブラウザ
uaMatch: function( ua ) {
ua = ua.toLowerCase();
// 各ブラウザを順番に照合します
var match = rwebkit.exec( ua ) || 🎜>ropera.exec(ua) ||
ua.indexOf("互換性") < rmozilla.exec(ua) ||
/ / match[1] || ""
// match[1] が false (空の文字列、null、未定義、0 など) の場合、デフォルトは ""
// match [2] || " 0"
// match[2] が false (空の文字列、null、未定義、0 など) の場合、デフォルトは "0"
return { browser: match[1 ] || "", version: match[2] || "0" };
},
// コピーのプロパティとメソッドは変更できます。 jQuery オブジェクトは影響を受けません
// 使用方法は 2 つあります:
// 1. 元のメソッドを破棄せずに jQuery メソッドをオーバーライドします
// 2. 名前空間の競合を回避するためにカプセル化し、jQuery の開発に使用できますplug-ins
// 注目に値します。さらに、jQuery.sub() 関数は実際の分離を提供しません。すべてのプロパティとメソッドは依然として元の jQuery を指します。
// このメソッドを使用してプラグインを開発する場合。 ins では、jQuery UI ウィジェット プロジェクトを優先することをお勧めします。
sub : function() {
function jQuerySub( selector, context ) {
return new jQuerySub.fn.init( selector, context );
}
jQuery.extend( true, jQuerySub, this ); // ディープコピー、jQuery のすべてのプロパティとメソッドを jQuerySub にコピーします。
jQuerySub.superclass = this;
jQuerySub.fn = jQuerySub。プロトタイプ = this(); //
jQuerySub.fn.constructor = jQuerySub;
jQuerySub.fn.init = function init( selector, context ) {
if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
context = jQuerySub( context )
}
return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); ;
};
jQuerySub.fn.init.prototype = jQuerySub.fn;
return jQuerySub;およびバージョン:
// $.browser.msie/mozilla/webkit/opera
// $.browser.version
// ブラウザーのタイプ jQuery.browser をスニッフィングすることはお勧めできませんが、ブラウザの機能 jQuery.support
// 将来、jQuery.browser はプラグインに移動される可能性があります
browser: {}
});