看jQuery.data(element/[key]">
Home > Web Front-end > JS Tutorial > Introduction to the jQuery object data cache Cache principle and the difference between jQuery.data methods_jquery

Introduction to the jQuery object data cache Cache principle and the difference between jQuery.data methods_jquery

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
Release: 2016-05-16 17:38:07
Original
1316 people have browsed it

There are many online tutorials on how to use jQuery.data(..) to implement data caching, but there are two commonly used by users: data([key],[value]) and jQuery.data(element,[key],[value]. ]) There are almost no articles that clearly explain the difference between the two, so I used it, studied it and shared it with everyone.

The difference between $("").data([key],[value]) and jQuery.data(element,[key],[value])
Both functions are used Storing data on elements is what we usually call data caching, and both return jQuery objects. I was really shocked when I used them both. The difference is huge. I really don’t need to know, but I was shocked when I used them. . Let’s look at the example first, and then analyze it based on the source code.

Js code:

Copy code The code is as follows:

test2

test3

test

aaaa


<script> <br>$(document ).ready(function(){ <br>$("#test").click(function(){ <br>alert("JQUERY"); <br>var e=$("div");// Two jquery objects are defined <br>var w=$("div"); //e is not equal to w. <br>//First use data([key],[value]) usage. (e).data("a","aaaa");//Save data with the same Key on e and w respectively, <br>$(w).data("a","wwww");// See if it will overwrite the previous one, although it is saved on a different object. <br>alert($(e).data("a"));//Have you guessed the answer? The output is wwww; right? A little unexpected? <br>alert(e===w)//false <br>alert($(w).data("a"));//This is also wwww; <br>//Use jQuery.data (element,[key],[value]) to store data. <br>$.data(e,"b","cccc");//Save the same data on e and w respectively, <br> $.data(w,"b","dddd");//See if it will overwrite the previous one, although it is saved on a different object. <br>alert($.data(e,"b")); //You should be able to guess the answer, output cccc <br>alert($.data(w,"b"));//This output dddd <br>}); <br>}); <br>< /script> <br><br> </div>After looking at the above example, did you find that data([key],[value]) and jQuery.data(element,[key],[value]) are not the same at all? Same thing, right? Is there any relationship between them? Why does data([key],[value]) overwrite the same value of the previous key? <br><br>And jQuery.data(element,[key],[value]) will not cause overwriting as long as it is bound to different objects. is that so? Let’s study their source code. <br><br>Look at the jQuery.data(element,[key],[value]) source code first. <br>Js code: <br><br><div class="codetitle"> <span><a style="CURSOR: pointer" data="90610" class="copybut" id="copybut90610" onclick="doCopy('code90610')">Copy code<u></u></a> The code is as follows: </span><div class="codebody" id="code90610"> <br>jQuery.extend({ <br>cache: {}, <br>// Please use with caution <br>uuid: 0, <br>// Unique for each copy of jQuery on the page <br>// Non-digits removed to match rinlinejQuery <br>expando: "jQuery" ( jQuery.fn.jquery Math.random() ).replace( /D/g, "" ), <br>.... <br>data: function( elem, name, data, pvt /* Internal Use Only */ ) { <br>// Whether data can be appended, if not, return directly <br>if ( !jQuery.acceptData( elem ) ) { <br>return; <br>} <br>var privateCache, thisCache, ret, <br>//jQuery.expando This is a unique string, which is generated when this jquery object is generated. 🎜>internalKey = jQuery.expando, <br>getByName = typeof name === "string", <br>// DOM elements and JS objects must be processed differently, because IE6-7 cannot garbage collect objects across DOM objects and JS objects Reference attribute <br>isNode = elem.nodeType, <br>// If it is a DOM element, use the global jQuery.cache <br>// If it is a JS object, attach it directly to the object <br>cache = isNode ? jQuery.cache : elem, <br>// Only defining an ID for JS objects if its cache already exists allows <br>// the code to shortcut on the same path as a DOM node with no cache <br> id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, <br>isEvents = name === "events"; <br>// Avoid doing more unnecessary work when trying to do something without any data When getting data on the object <br>// The object does not have any data, directly return <br>if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data) ) && getByName && data === undefined ) { <br>return; <br>} <br>// If the id does not exist, generate one <br>if ( !id ) { <br>// Only DOM nodes need a new unique ID for each element since their data <br>// ends up in the global cache <br>if ( isNode ) { <br>// If it is a DOM element, generate a unique ID on the element and use jQuery. expando <br>//Save the attribute value as id on the elem element so that you can find the ID based on jQuery.expando later. <br>elem[ internalKey ] = id = jQuery.uuid; <br>} else { <br>//JS objects use jQuery.expando directly. Since it is directly attached to the object, why do we need the id? <br>// Avoid conflicts with other attributes! <br>id = internalKey; <br>} <br>} <br>//// When we try to access whether a key contains a value, if the jQuery.cache[id] value does not exist, <br>/ / Initialize jQuery.cache[id] value to an empty object {} <br>if ( !cache[ id ] ) { <br>cache[ id ] = {}; <br>if ( !isNode ) { <br> cache[ id ].toJSON = jQuery.noop; <br>} <br>} <br>// An object can be passed to jQuery.data instead of a key/value pair; this gets <br>// shallow copied over onto the existing cache <br>// data is to receive objects and functions, shallow copy <br>if ( typeof name === "object" || typeof name === "function" ) { <br>if ( pvt ) { <br>cache[ id ] = jQuery.extend( cache[ id ], name ); <br>} else { <br>cache[ id ].data = jQuery.extend( cache[ id ].data, name ); <br>} <br>} <br>/ Storage object, a mapping object that stores all data <br>privateCache = thisCache = cache[ id ]; <br>// jQuery data() is stored in a separate object inside the object's internal data <br>// cache in order to avoid key collisions between internal data and user-defined <br>// data. <br>// jQuery internal data exists in a separate object (thisCache.data= =thisCache[ internalKey ]) <br>//On, in order to avoid conflicts between internal data and user-defined data <br>if ( !pvt ) { <br>// The object storing private data does not exist, create one {} <br>if ( !thisCache.data ) { <br>thisCache.data = {}; <br>} <br>// Replace thisCache with a private data object <br>thisCache = thisCache.data; <br>} <br>// If data is not undefined, it means that the data parameter is passed in, then the data is stored in the name attribute <br>if ( data !== undefined ) { <br>// The function of jQuery.camelCase( name ) is if it is passed in It is object/function, no conversion is done, <br>//Only the name passed in is a string will be converted. So what is finally saved is the key/value pair; <br>thisCache[ jQuery.camelCase( name ) ] = data; <br>} <br>//From now on, the following code processes data: function( elem, name) data is empty, find out the return value data. <br>if ( isEvents && !thisCache[ name ] ) { <br>return privateCache.events; <br>} <br>// If name is a string, return data <br>// If not, return Entire storage object <br>if ( getByName ) { <br>// First Try to find as-is property data <br>ret = thisCache[ name ]; <br>// Test for null|undefined property data <br> if ( ret == null ) { <br>// Try to find the camelCased property <br>ret = thisCache[ jQuery.camelCase( name ) ]; <br>} <br>} else { <br>ret = thisCache ; <br>} <br>return ret; <br>}, <br>............ <br>}); <br><br><br>Please see the picture<br><img src="http://files.jb51.net/file_images/article/201304/201347154622592.jpg?201337154725" alt="Introduction to the jQuery object data cache Cache principle and the difference between jQuery.data methods_jquery" > <br>Looking at the jQuery.data(element,[key],[value]) source code, you can know that each element will have its own {key:value} object The data is saved, so even if the newly created object has the same key, it will not overwrite the value corresponding to the key of the original existing object, because the new object is saved in another {key:value} object. <br><br> Next, we need to analyze the source code of data([key],[value]), which uses each(callback). Before analyzing it, let’s take a look at the usage and source code of each(callback). <br><br>Js code: <br><div class="codetitle"> <span><a style="CURSOR: pointer" data="68584" class="copybut" id="copybut68584" onclick="doCopy('code68584')"><u>Copy code </u></a></span> The code is as follows: </div> <div class="codebody" id="code68584"> <br><div id="test2" onclick="test()">test2</div> <br><div id="abc3" onclick="test()">test3</div> <br><div id="test" onclick="test()">test</div> <br><p id="ttt">aaaa</p> <br><script> <br>$(document ).ready(function(){ <br>$("#test").click(function(){ <br>alert("JQUERY"); <br>var i=0; <br>$("# abc3").each(function() { <br>alert( i);//Only output 1; because there is only one <div id="abc3"> <br>}); <br>alert("- ---"); <br>var j=0; <br>$("div").each(function() { <br>alert( j);//Output 1, 2, 3 respectively; because there are three <br>}); <br>}); <br></script>
Now let’s look at the specific implementation of each method as follows:
jQuery.fn = jQuery.prototype = {
each: function( callback, args ) {
return jQuery.each( this, callback, args );
}
}
You can see What it returns is the global each method, and its own jQuery object is given to it as a parameter. The specific implementation of the global each method is as follows:
// args is used as a call to internal members
each: function( object, callback, args ) {
var name, i = 0, length = object.length; // When object is a jQuery object, length is not empty
if ( args ) {
if ( length = == undefined ) {
for ( name in object )
if ( callback.apply( object[ name ], args ) === false )
break;
} else
for ( ; i < length; )
if ( callback.apply( object[ i ], args ) === false )
break;
// The following is the client program to call
} else {
if ( length === undefined ) {
for ( name in object )
if ( callback.call( object[ name ], name, object[ name ] ) === false )
break;
} else
// i represents the index value, value represents the DOM element
for ( var value = object[0];
i < length && callback.call( value, i , value ) !== false;
value = object[ i] ){}
}
return object;
}

Now we focus on for ( var value = object[0]; i < length && callback.call( value, i, value ) !== false; value = object[ i] ){} This code; where object[0] gets the jQuery object For the first DOM element, through the for loop,
gets to traverse each corresponding DOM element in the entire jQuery object, and through callback.call(value,i,value); point the callback's this object to the value object, and pass two Parameters, i represents the index value, value represents the DOM element; callback is a method similar to function(index, elem) { }. So we get $("").each(function(index, elem){ });
Let’s look at the source code of data([key],[value])
Js code:

Copy code The code is as follows:

jQuery.fn.extend({
data: function( key, value) {
var parts, part, attr, name, l,
elem = this[0],
i = 0,
data = null;
// Gets all values ​​
if ( key === undefined ) {
.....//Handle the case without Key, here Not what we are going to discuss
return data;
}
// Sets multiple values ​​
if ( typeof key === "object" ) {
return this.each(function() {
jQuery.data( this, key );
});
}
parts = key.split( ".", 2 );
parts[1] = parts[1] ? "." parts[1] : "";
part = parts[1] "!";
return jQuery.access( this, function( value ) {
if ( value === undefined ) {
. . //Here is the case of getting the return value when there is no value. This is not what we are talking about.
parts[1] = value;
//If I use $("div").data("a","aaa")), this before calling each below refers to the object returned by $("div"),
this.each(function() { //Note, here we use each matching element as the context to execute a function
var self = jQuery( this );
self.triggerHandler( "setData" part, parts );
// The data stored on the element here is essentially delegated to data(element, [key], [value]).
//See the previous analysis.
//The following data(this, key, value) refers to traversing each corresponding DOM element in the entire jQuery object
//$("div"), which corresponds to a
array in the page.
jQuery.data( this, key, value );//This statement will be executed in a loop multiple times, that is, the data is saved .
//Here is the core sentence. But please see clearly above that it is in each(functipn(){}).
self.triggerHandler( "changeData" part, parts );
});
}, null, value, arguments.length > 1, null, false );
},
//Remove stored data on the element. The specific implementation is as follows:
removeData: function( key ) {
return this.each(function() {
jQuery.removeData( this, key );
});
}
});

If you don’t know much about the source code of data([key],[value]), well, I will use an example to imitate it.
Js code:

Copy code The code is as follows:
test2

test3

test

aaaa


<script> <br>$(document).ready (function(){ <br>$("#test").click(function(){ <br>alert("JQUERY"); <br>var i=0; <br>$("#abc3") .each(function() { <br>alert( i);//Only output 1; because there is only one <div id="abc3"> <br>}); <br>alert("---- "); <br>var j=1; <br>$("div").each(function() {//Execute this function with each matching element as the context<br>$.data(this, "a","wwww");//This here refers to $("div"), <br>//Traverse each matching element separately and save a key/value for each of their objects {} <br>alert(j );//Output 1, 2, 3 respectively because there are three <div> elements <br>}); <br>alert($("#test").data("a")); //Return to wwww, <br>//Aren't you surprised? I didn't save it in it. Why is there a value? It's obvious that it is checking whether there is one on this div node. <br>//There must be a value. Yes, because the above loop is saved in the Dom node of div <br>alert($("#test")===$("div"));//false proves that the two newly created objects are not the same. . <br>alert($("div").data("a"));//Return wwww, <br>//The same is true here because "a"="wwww" is saved on the div node. A key value is correct. <br>}); <br>}); <br></script>

Now for data([key],[value]) with jQuery. You already understand data(element,[key],[value]). If you still don’t understand it, go back and read it again and patiently understand it. In fact, it looks very different on the surface. But there is still a connection in essence. Now that you understand the principle, you can use it with confidence. jQuery.data(element,[key],[value]) only binds data to the parameter element node. data([key],[value])
For example, $("div").data("a","aaaa") binds data to each element that matches the div node.
As an additional note, the source code of jquery-1.7.2.js is used in the analysis in this article. Download address:
http://demo.jb51.net/jslib/jquery/jquery-1.7.2.min.js
Related labels:
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template