jQueryでのデータ操作方法とjQueryの定義
この記事では、jQuery でのデータ操作の方法と jQuery の定義について説明します。必要な方は参考にしていただければ幸いです。
jQuery にはデータ操作のメソッドが 2 つあります
$().data() $.data(elem);
内部実装はカスタム クラス Data
から分離できませんData
内部类 Data
Data
在src/data/Data.js
定义,构建时为实例添加expando
属性,作为唯一标识
function Data() { this.expando = jQuery.expando + Data.uid++; }
在原型上添加了多个方法
Data.prototype = { cache: function(){ ... }, set: function(){ ... }, get: function(){ ... }, access: function(){ ... }, remove: function(){ ... }, hasData: function(){ ... } }
在jq内部,使用cache方法获取缓存的数据。传入一个参数owner,表示要获取缓存数据的对象。判断在owner上是否有expando属性,如果没有,说明这个owner是否第一次调用,需要在其初始化缓存数据对象。判断节点的类型,如果是元素节点或者document节点或者对象时,可以设置缓存数据。如果是元素节点或者document节点,直接使用对象字面量进行赋值,属性名是expando,值为空对象。如果是对象的话,使用Object.defineProperty
为其定义数据,属性名也是expando,初始化为{},同时属性描述符可以更改,不可枚举。
Data.prototype.cache
cache: function( owner ) { // Check if the owner object already has a cache // 获取在owner的缓存值 var value = owner[ this.expando ]; // If not, create one if ( !value ) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. // 判断owener类型 是否能在其上调用data // 在元素节点或body或对象上可以设置data // 其他节点不设置缓存数据 if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment // 此处为owner添加属性 key为Data对象的expando值 建立owner和Data对象之间的连接 // owner是元素节点或body if ( owner.nodeType ) { owner[ this.expando ] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed // owner是对象 // 为owner添加expando属性 初始化为{},同时属性描述符可以更改,不可枚举 } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } return value; }
使用set
来更新缓存对象,分为data(key,value)
或data(obj)
两种调用情况,保存时要将键名保存为驼峰命名法。
Data.prototype.set
set: function( owner, data, value ) { var prop, cache = this.cache( owner ); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if ( typeof data === "string" ) { cache[ jQuery.camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for ( prop in data ) { cache[ jQuery.camelCase( prop ) ] = data[ prop ]; } } return cache; }
使用get
来获取缓存对象,调用时有data(key)
和data()
。未指定key时直接返回整个cache对象,否则返回cache[key]。键名也要转为驼峰命名。
Data.prototype.get
get: function( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; }
对调用的方式进行区分,内部调用 set
或get
通过参数的数量和类型进行区分:
key为空时,获取整个cache对象
key类型为
string
且value===undefined
对应获取指定值其他调用均为
set
,在set
内部进行区分
Data.prototype.access
access: function( owner, key, value ) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if ( key === undefined || ( ( key && typeof key === "string" ) && value === undefined ) ) { return this.get( owner, key ); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set( owner, key, value ); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }
使用remove
来删除缓存对象属性,调用时,可以传入一个string,表示要删除的键名,或者传入一个保存多个键名的string数组。键名也要转为驼峰命名。如果不传入出参数,则直接删除掉在owner上的缓存数据对象。
Data.prototype.remove
remove: function( owner, key ) { var i, cache = owner[ this.expando ]; if ( cache === undefined ) { return; } if ( key !== undefined ) { // Support array or space separated string of keys if ( Array.isArray( key ) ) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map( jQuery.camelCase ); } else { key = jQuery.camelCase( key ); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [ key ] : ( key.match( rnothtmlwhite ) || [] ); } i = key.length; while ( i-- ) { delete cache[ key[ i ] ]; } } // Remove the expando if there's no more data if ( key === undefined || jQuery.isEmptyObject( cache ) ) { // Support: Chrome <=35 - 45 // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if ( owner.nodeType ) { owner[ this.expando ] = undefined; } else { delete owner[ this.expando ]; } } }
判断owner上是否有缓存数据。
Data.prototype.hasData
hasData: function( owner ) { var cache = owner[ this.expando ]; return cache !== undefined && !jQuery.isEmptyObject( cache ); }
jQuery方法的定义
定义后内部类data
后,在/src/data.js
进行拓展。在jQuery添加了hasData
、data
、 removeData
、_data
、_removeData
等方法,在jQuery.fn上添加了data
和removeData
方法。
在jQuery拓展的方法,都是对Data方法的封装,在调用时$.data()
时,并无对set
和get
操作区分,在Data.prototype.access
内部区分set和get。下面源码中,dataUser
和dataPriv
是Data
实例,分别为缓存数据和表示jq对象是否将元素的data属性添加到dataUser
中
// $.data jQuery.extend( { hasData: function( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } );
在jQuery.fn
上拓展的方法只有data
和removeData
。在data
内,先对$().data()
和$().data({k:v})
两个调用情况进行处理。如果是第一种情况,则返回在this[0]
上的缓存数据对象,如果是第一次以$().data()
的方式调用,同时还会将元素上的data属性添加dataUser
中,并更新dataPriv
。如果是$().data({k:v})
的调用方式,则遍历jq对象,为每个节点更新缓存数据。其他调用方式如$().data(k)
和$().data(k,v)
则调用access
进行处理。此处的access
并非Data.prototype.access
。
removeData
则遍历jq对象,删除在每个节点上的缓存数据。
// $().data jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], // elem为dom对象 attrs = elem && elem.attributes; // 节点上的属性 // Gets all values // $().data() if ( key === undefined ) { if ( this.length ) { data = dataUser.get( elem ); // elem是元素节点,且dataPriv中无hasDataAttrs时执行这个代码块里的代码 // dataPriv上的hasDataAttrs表示elem是否有data-xxx属性 // 初始化dataPriv后花括号内的代码不再执行,即以下的if内的代码只执行一次 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { // Support: IE 11 only // The attrs elements can be null (#14894) // 将elem的data-*-*属性以*-*转为驼峰命名方式的值为键 // 在dataAttr函数内保存到dataUser中 // 所以用$().data可以获取元素的data-*属性 但修改后dom上的属性却不变化 if ( attrs[ i ] ) { name = attrs[ i ].name; // name为data-xxx if ( name.indexOf( "data-" ) === 0 ) { // name为xxx name = jQuery.camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } // 同时将dataPriv的hasDataAttrs属性设置为真,表示已经将元素属性节点上的data属性保存到缓存对象中 dataPriv.set( elem, "hasDataAttrs", true ); } } return data; } // Sets multiple values // $().data(obj) 此处遍历this,即遍历jq对象上所有的节点,并在其设置值 if ( typeof key === "object" ) { return this.each( function() { dataUser.set( this, key ); } ); } // 除了$().data()和$().data({k:v})的其他情况 return access( this, function( value ) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. // value undefined说明是获取操作 // 调用$().data(k) if ( elem && value === undefined ) { // Attempt to get data from the cache // The key will always be camelCased in Data // 从dataUser中获取 非undefined时返回 data = dataUser.get( elem, key ); if ( data !== undefined ) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs // dataUser中不存在key,调用dataAttr查找元素的data-*属性 // 如果存在属性,更新dataUser并返回其值 data = dataAttr( elem, key ); if ( data !== undefined ) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... // jq对象长度 >= 1, 调用如$().data(k,v) 遍历jq对象,为每个节点设置缓存数据 this.each( function() { // We always store the camelCased key dataUser.set( this, key, value ); } ); }, null, value, arguments.length > 1, null, true ); }, // 遍历jq对象,删除各个元素上的缓存数据 removeData: function( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } );
其中,getData
用于对元素上的data属性进行类型转换,dataAttr
用于获取保存在元素节点上的data属性,并同时更新dataUser
。需要注意的是,以$().data(k, v)
方式调用时,如果在缓存数据上查找不到属性,则会调用dataAttr
内部クラス Data
Data
は src/data/Data.js
で定義されます。ビルド時に、expando
属性を一意の識別子としてインスタンスに追加します
// 属性值是string 进行类型转换 function getData( data ) { if ( data === "true" ) { return true; } if ( data === "false" ) { return false; } if ( data === "null" ) { return null; } // Only convert to a number if it doesn't change the string // data转化成number再转成string后仍严格等于data if ( data === +data + "" ) { return +data; } if ( rbrace.test( data ) ) { return JSON.parse( data ); } return data; } // 获取元素的dataset中的属性,并保存到dataUser中 function dataAttr( elem, key, data ) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute // 此处获取dataset里的值 if ( data === undefined && elem.nodeType === 1 ) { name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); // 此处将驼峰命名方式的key转化为data-*-* data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = getData( data ); } catch ( e ) {} // Make sure we set the data so it isn't changed later // 将元素的data-*属性保存到dataUser中 dataUser.set( elem, key, data ); } else { data = undefined; } } return data; }
Data.prototype.cache
rrreeeset
を使用して、data(key, value)
に分割されたキャッシュ オブジェクトを更新します> または data(obj)
どちらの呼び出しの場合でも、保存時にキー名をキャメルケースで保存する必要があります。 🎜Data.prototype.set
rrreee🎜 get
を使用してキャッシュ オブジェクトを取得します。呼び出し時に、data(key) と <code>data()
。キーが指定されていない場合は、キャッシュ オブジェクト全体が直接返され、それ以外の場合は、cache[key] が返されます。キー名もキャメルケースに変換する必要があります。 🎜Data.prototype.get
rrreee🎜呼び出しメソッドを区別し、内部的に set
または get
を呼び出します🎜🎜 区別しますパラメータの数とタイプ: 🎜- 🎜key が空の場合、キャッシュ オブジェクト全体を取得します 🎜
- 🎜key のタイプは
文字列です
とvalue===unknown
は、指定された値の取得に対応します🎜 - 🎜その他の呼び出しは、
setset
です。 /code> 内部区別🎜
Data.prototype.access
rrreee🎜キャッシュされたオブジェクト属性を削除するには、remove
を使用します。呼び出し時に、削除するキー名を表す文字列を渡すことも、複数のキー名を保持する文字列配列を渡すこともできます。キー名もキャメルケースに変換する必要があります。パラメータが渡されたり渡されたりしない場合、所有者のキャッシュされたデータ オブジェクトは直接削除されます。 🎜Data.prototype.remove
rrreee🎜 所有者にキャッシュされたデータがあるかどうかを確認します。 🎜Data.prototype.hasData
rrreee🎜jQuery メソッドの定義🎜🎜 内部クラス data
を定義した後、 /src/data.js
が展開されます。 hasData
、data
、removeData
、_data
、_removeData
およびその他のメソッドを jQuery に追加しました、jQuery.fn に data
メソッドと removeData
メソッドを追加しました。 🎜🎜 jQuery で拡張されたメソッドはすべて Data メソッドのカプセル化です。$.data()
を呼び出す場合、set
と get
はサポートされません。 code>操作の区別。Data.prototype.access
内の set と get を区別します。以下のソース コードでは、dataUser
と dataPriv
は Data
のインスタンスであり、それぞれデータをキャッシュし、jq オブジェクトが要素のデータ属性を追加するかどうかを示します。 jQuery.fn
の >dataUser 内の 🎜rrreee🎜 によって拡張されたメソッドは、data
と removeData
だけです。 data
で、まず $().data()
と $().data({k:v})
の 2 つの呼び出しを行います。状況は処理されます。最初のケースの場合、 $().data()
を初めて呼び出す場合は、 this[0]
のキャッシュされたデータ オブジェクトが返されます。また、要素の data 属性を dataUser
に追加し、dataPriv
を更新します。 $().data({k:v})
の呼び出しメソッドの場合、jq オブジェクトが走査され、キャッシュされたデータがノードごとに更新されます。 $().data(k)
や $().data(k,v)
などの他の呼び出しメソッドは、処理のために access
を呼び出します。ここでの access
は Data.prototype.access
ではありません。 🎜🎜removeData
は、jq オブジェクトを走査し、各ノードのキャッシュされたデータを削除します。 🎜rrreee🎜 このうち、getData
は要素のデータ属性の型変換を行うために使用され、dataAttr
は要素ノードに保存されているデータ属性を取得するために使用され、同時に dataUser
も更新します。 $().data(k, v)
で呼び出すときに、キャッシュされたデータで属性が見つからない場合は、dataAttr
が呼び出されることに注意してください。要素 プロパティを検索します。 🎜rrreee🎜おすすめ関連記事: 🎜🎜🎜Angularフォーム検証の2つの方法の紹介🎜🎜JavaScript関数の使い方?JavaScript関数のプロパティとメソッドの紹介
以上がjQueryでのデータ操作方法とjQueryの定義の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









jQuery 参照方法の詳細説明: クイック スタート ガイド jQuery は、Web サイト開発で広く使用されている人気のある JavaScript ライブラリであり、JavaScript プログラミングを簡素化し、開発者に豊富な機能を提供します。この記事では、jQuery の参照方法を詳しく紹介し、読者がすぐに使い始めるのに役立つ具体的なコード例を示します。 jQuery の導入 まず、HTML ファイルに jQuery ライブラリを導入する必要があります。 CDN リンクを通じて導入することも、ダウンロードすることもできます

jQueryでPUTリクエストメソッドを使用するにはどうすればよいですか? jQuery で PUT リクエストを送信する方法は、他のタイプのリクエストを送信する方法と似ていますが、いくつかの詳細とパラメータ設定に注意する必要があります。 PUT リクエストは通常、データベース内のデータの更新やサーバー上のファイルの更新など、リソースを更新するために使用されます。以下は、jQuery の PUT リクエスト メソッドを使用した具体的なコード例です。まず、jQuery ライブラリ ファイルが含まれていることを確認してから、$.ajax({u

jQueryで要素の高さ属性を削除するにはどうすればよいですか?フロントエンド開発では、要素の高さ属性を操作する必要が生じることがよくあります。要素の高さを動的に変更する必要がある場合や、要素の高さ属性を削除する必要がある場合があります。この記事では、jQuery を使用して要素の高さ属性を削除する方法と、具体的なコード例を紹介します。 jQuery を使用して高さ属性を操作する前に、まず CSS の高さ属性を理解する必要があります。 height 属性は要素の高さを設定するために使用されます

タイトル: jQuery ヒント: ページ上のすべての a タグのテキストをすばやく変更する Web 開発では、ページ上の要素を変更したり操作したりする必要がよくあります。 jQuery を使用する場合、ページ内のすべての a タグのテキスト コンテンツを一度に変更する必要がある場合があります。これにより、時間と労力を節約できます。以下では、jQuery を使用してページ上のすべての a タグのテキストをすばやく変更する方法と、具体的なコード例を紹介します。まず、jQuery ライブラリ ファイルを導入し、次のコードがページに導入されていることを確認する必要があります: <

タイトル: jQuery を使用して、すべての a タグのテキスト コンテンツを変更します。 jQuery は、DOM 操作を処理するために広く使用されている人気のある JavaScript ライブラリです。 Web 開発では、ページ上のリンク タグ (タグ) のテキスト コンテンツを変更する必要が生じることがよくあります。この記事では、この目標を達成するために jQuery を使用する方法を説明し、具体的なコード例を示します。まず、jQuery ライブラリをページに導入する必要があります。 HTML ファイルに次のコードを追加します。

jQuery 要素に特定の属性があるかどうかを確認するにはどうすればよいですか? jQuery を使用して DOM 要素を操作する場合、要素に特定の属性があるかどうかを判断する必要がある状況がよく発生します。この場合、jQuery が提供するメソッドを使用してこの関数を簡単に実装できます。以下では、jQuery 要素が特定の属性を持つかどうかを判断するために一般的に使用される 2 つの方法を紹介し、具体的なコード例を添付します。方法 1: attr() メソッドと typeof 演算子 // を使用して、要素に特定の属性があるかどうかを判断します

jQuery は、Web ページでの DOM 操作やイベント処理を処理するために広く使用されている人気のある JavaScript ライブラリです。 jQueryではeq()メソッドを利用して指定したインデックス位置の要素を選択しますが、具体的な使い方と応用シーンは以下の通りです。 jQuery では、 eq() メソッドは、指定されたインデックス位置にある要素を選択します。インデックス位置は 0 からカウントされます。つまり、最初の要素のインデックスは 0、2 番目の要素のインデックスは 1 などとなります。 eq() メソッドの構文は次のとおりです。 $("s

jQuery は、Web 開発で広く使用されている人気の JavaScript ライブラリです。 Web 開発中は、JavaScript を使用してテーブルに新しい行を動的に追加することが必要になることがよくあります。この記事では、jQuery を使用してテーブルに新しい行を追加する方法を紹介し、具体的なコード例を示します。まず、jQuery ライブラリを HTML ページに導入する必要があります。 jQuery ライブラリは、次のコードを通じてタグに導入できます。
