ホームページ  >  記事  >  ウェブフロントエンド  >  jqueryバインディング原理の簡単な分析と実装コードsharing_jquery

jqueryバインディング原理の簡単な分析と実装コードsharing_jquery

WBOY
WBOYオリジナル
2016-05-16 18:02:36778ブラウズ

jq には、関連するデータを DOM 要素にバインドする data メソッドがあります。 jq メソッドを使用してイベントが dom にバインドされると、対応する時刻リストが生成されます
以下の例を確認できます (Firefox のオブジェクトは toSource() をサポートしているため、Firefox で表示してください)

コードをコピーします コードは次のとおりです。


>

;/head>



;/body>



データは要素にバインドするために使用されます
データ ソースはキャッシュ オブジェクトです
要素がデータにバインドされる場合、 jq実行のタイムスタンプとして属性jQueryxxx xxxが要素に追加されます
ここで蓄積されるuuidがあることを説明します
jQueryxxxの値はこのuuidです
キャッシュのキーこれは uuid です
値は保存されるデータです
データはイベント バインディングにとって非常に重要です....................



コードをコピー コードは次のとおりです: function now(){
return new Date ;
};
var win = this、
expando = "jQuery" now()、
cache = {}; elem, 名前, データ){
var id = elem[expando];
if(!id)
id = elem[expando] = uuid;
if(name&&!cache[id])
キャッシュ[id] = {};
if(データ !== 未定義)
キャッシュ[id][名前] = データ;
キャッシュ[id][名前]を返しますか? ]
: id;
}
win.removeData = function(elem, name){
var id = elem[expando];
if (name){
if (キャッシュ) [id]) {
キャッシュ[id][name];
name = "";
for ( キャッシュ[ id ] )
if ( !name )
removeData(elem);
}
}else{
try {
delete elem[expando];
} catch(e){
if ( elem.removeAttribute )
elem.removeAttribute(expando );
}
キャッシュ[id]を削除します
}
}
win.each = function( object, callback, args ) {
var name, i = 0, length = object.length;
if ( args ) {
if ( length === unknown ) {
for ( object 内の名前 )
if ( callback.apply ( object[ name ], args ) === false )
break;
} else
for ( ; i if ( callback.apply( object[ i ], args ) === false )
break;
} else {
if ( length === 未定義 ) {
for ( オブジェクト内の名前 )
if ( callback.call( object[ name ], name, object[ name ] ) === false )
break;
} else
for ( var value = object[0];
i < length && callback.call( value , i, value ) !== false; value = object[ i] ){}
}
return object;


次に、イベント
jq を追加します。これは jQuery.event にあります。 追加メソッド
は、追加メソッドにいくつかの関数を実装します。
要素のイベントを取得し、これら 2 つのデータによってバインドされたデータを処理します。
イベントは、イベント リストを保存します。
形式
{
click: [{handler:function(){},type:"click",guid:'xx'}....],
mouse:[... ...]
}
ハンドルは実行された関数です
(すべての実行関数は同じです。これらはイベント リストを走査して対応するイベントを実行します)
次に、複数のイベントを実行できるため、タイプを走査します。バウンド
コールバック関数にもいくつかの属性があります
コールバック関数がハンドラーであると仮定します
handler.guid = gevent.guid
handler.type = name
name は特別な名前であると見なされます簡単に削除するには
など
$('#xx')
.bind('click',function(){})
.bind('click.d',handler)
名前は d
削除 上記のクリック イベントを削除せずに d イベントのみを削除できます
最後に、イベントを要素にバインドしますが、実行される関数はすべて
function(){
gevent .handle.apply(arguments.callee .elem, argument);




コードをコピーします


コードは次のとおりです以下:

win.gevent = {
guid : 1,
add : function (elem, Types, handler){
if ( elem.nodeType == 3 || elem.nodeType == 8)
return;
if ( elem.setInterval && elem != window )
elem = window;
//後でイベントを削除しやすくするために関数に一意のインデックスを与えます
if ( !handler.guid )
handler.guid = this.guid
//要素のイベント ハンドルの下のデータを取得します。
var events = data(elem, "events") || , "events", {}),
handle =data(elem, "handle") || data(elem, "handle", function(){
//gevent.handle はさまざまな動作がトリガーされるときです実行される関数
gevent.handle.apply(arguments.callee.elem, argument);
handle.elem = elem;
//イベント名をトラバースします。マウスオーバーでクリックすることもできます
each(types.split(/s /), function(index, type) {
var namespaces = type.split(".");
//イベント名を取得します
type = namespaces .shift();
//ドット以降は特殊な名前で削除する場合は click.d のように指定できます
//イベントタイプを使用します。この特別な名前を記録するには
handler .type = namespaces.slice().sort().join(".");
//イベントがイベント オブジェクトに既に存在するかどうかを取得します
var handlers = events[type];
//イベントが存在しない場合は、イベントを要素にバインドします
if (!handlers) {
handlers = events[type] = {}; elem.addEventListener)
elem.addEventListener (type, handle, false);
else if (elem.attachEvent)
elem.attachEvent("on" type, handle); // リスト内の要素のイベントに関数を配置します。
handlers[handler.guid] = handler;
}
}


gevent.hander がバインドされています。 イベントの実際の実行を決定する関数
も gevent.hander で使用できます。この場所は特別に名前が付けられていますが、何に使用されるのかはわかりません。 🎜>ハンドラーでは、最初にイベントがパッケージ化されます
パッケージ化については、gevent.fix と setEvent を参照してください
主にネイティブ イベントのコピーを作成し、互換性のないメソッドを互換性のある記述に合成します
次に、イベントを取得します要素
の (イベント リスト) 次に、イベント リストを走査して、その型がイベント リストのキーであるかどうかを判断します。そうであれば、イベントを実行します。
戻り値は、リスト関数の実行時に判断されます
false が返された場合、イベントのバブリングやデフォルトの動作も整理できます




コードをコピー


コードは次のとおりです:

win.gevent = {
handle : function(event){
var all, handlers;
//イベントをパッケージ化
event = argument[0] = gevent.fix(イベント || window.event );

event.currentTarget = this;

//ここで
var namespaces =event.type.split( "."); 🎜>event.type = namespaces.shift();
all = !namespaces.length;
var namespace = RegExp("(^|\.)" namespaces.slice().sort().join( ".*\.") "(\.|$)");
//この要素のこの動作のイベント リストを取得します
handlers = (data(this, "events" ) || {} )[event.type];
//このイベント リストを走査して、実行内容を実行します
for ( var j in handlers ) {
var handler = handlers[j];
if ( all | | namespace.test(handler.type) ) {
// ハンドラー関数自体への参照を渡します
// 後で削除できるように
// jq でコメントは次のように記述されます. イベント ハンドラーは便宜上このイベントを参照しており、後で削除できます。
// ただし、イベント ハンドラーは削除では使用されません。また、複数のイベントがある場合、これが使用されます。イベントは Replace
event.handler = handler;
//イベントを実行し、要素で呼び出されるイベントでこれを関数 < の戻り値として要素 ret を実行するために使用できます。 🎜>var ret = handler.apply(this, argument);
//戻り値があり、その戻り値が false の場合、イベントのバブリングが防止され、デフォルトの動作が防止されます。 🎜>if( ret !== 未定義 ){
event.result = ret;
if ( ret === false ) {
event.preventDefault();
event.stopPropagation();
}
}
}
}
},
props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget datadetail eventsPhase fromElement handler keyCode metaKey newValueoriginalTarget pageX pageY prevValue requiredNoderelationTargetscreenXscreenYshiftKeysrcElementtargettoElementviewwheelDeltathat".split(" "),
fix : function(event){
//new setEvent はイベントに Expando 属性を与えます。属性がある場合、イベントが生成されたことを意味します。イベントを再度ラップする必要はありません。
if (event[expando] )
//元のイベントを保持します。
// new新しいイベント これは元のイベントとは異なります
varoriginalEvent =event;
event = new setEvent (originalEvent)
//元のイベントの属性値を取得するには、this.props を参照してください。
for ( var i = this.props.length, prop; i; ){
prop = this.props[ --i ];
event[ prop ] = originalEvent[ prop ]; }
//ターゲット要素をevent.targetに統合します
if ( !event.target )
event.target = events.srcElement || // srcElementが定義されていない可能性がある#1925を修正します。
//テキストノードであることが判明した場合は、その親ノードを取得します
if (event.target.nodeType == 3)
event.target =event.target.parentNode; ( !event.popularTarget &&event.fromElement )
event.popularTarget =event.fromElement ==event.toElement : イベント

}
; >win.setEvent = function(src){
// 'new' キーワードなしでインスタンス化を許可します
// イベント オブジェクト
if( src && src.type ){
this.originalEvent = src ;
this.type = src.type;
// イベントタイプ
}else
this.type = src; // Firefox の一部のイベントでは timeStamp がバグります(#3843)
// したがって、ネイティブ値には依存しません
this.timeStamp = now();
// 固定としてマークします
this[expando] = true;
関数 returnFalse(){
return false;
}
function returnTrue(){
return true;
}
setEvent.prototype = {
preventDefault: function( ) {
var e = this.originalEvent;
if( !e )
return;
//PreventDefault が存在する場合は、元のイベントで実行します
if (e.preventDefault)
e.preventDefault();
// それ以外の場合は、元のイベントの returnValue プロパティを false に設定します (IE)
e. returnValue = false;
stopPropagation: function() 🎜>var e = this.originalEvent;
if( !e )
return;
// stopPropagation が存在する場合は、元のイベントで実行します
if (e.stopPropagation)
e。 stopPropagation();
// それ以外の場合は、元のイベントの cancelBubble プロパティを true に設定します (IE)
e.cancelBubble = true ;
},
stopImmediatePropagation:function(){
this .isImmediatePropagationStopped = returnTrue;
this.stopPropagation();
isImmediatePropagationStopped: returnFalse
}; >

コードをコピーします


コードは次のとおりです:














声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。