Preface
I believe that jQuery's data cache will not be unfamiliar to anyone. The jQuery cache system is used not only for DOM elements, but also for animations and events. Therefore, in actual applications, we often need to cache some data for elements, which are often closely related to DOM elements. Because DOM elements (nodes) are also objects, we can directly extend the attributes of DOM elements. However, if we add custom attributes and excessive data to DOM elements, memory leakage may occur, so we should try to avoid this. Therefore, a better solution is to use a low coupling method to connect the DOM with the cached data.
In addition, the introduction and usage of jQuery. data and jQuery. removeData static methods and prototype extension methods based on these two methods are not described. You can refer to the official API documentation.
Implementation
JQuery provides a flexible and powerful caching method:
(1) create a cache object {} In jQuery to save the cached data. Then extend an attribute with the value of expando to the DOM node to be cached. Here it is "jQuery" + (new Date). getTime (). Note: The expando value is equal to "jQuery" + current time, and the element itself has very little possibility of this attribute, so you can ignore the conflict.
(2) set the dom [expando] value of each node to an auto-Increment Variable id to ensure global uniqueness. The value of this id is used as the cache key to associate DOM nodes and data. That is to say, the cache [id] gets all the caches on this node, that is, the id is like the key to open a room (DOM node. All the caches of each element are stored in a map ing, so that multiple data can be cached at the same time.
(3) The cache object structure should be as follows:Copy codeThe Code is as follows: var cache = {
"Uuid1": {// DOM Node 1 caches data. "uuid1" is equivalent to dom1 [expando]
"Name1": value1,
"Name2": value2
},
"Uuid2": {// DOM Node 2 caches data. "uuid2" is equivalent to dom2 [expando]
"Name1": value1,
"Name2": value2
}
//......
};
Each uuid corresponds to an elem cached data. Each cached object can be composed of multiple name/value pairs, and value can be of any data type.
Simple simulation
Based on the above ideas, you can simply implement the functions of jQuery. data and jQuery. removeDate:Copy codeThe Code is as follows: (function (window, undefined ){
Var cacheData ={}, // object used to store data
Win = window, // cache the window to a variable
Uuid = 0,
// Declare a random number (8 digits)
// Note that the random Number generated by + new Date () is of the Number type. The slice method can be used only when it is changed to a string after it is connected to an empty string (or after transformation using the toString method.
Expando = "cacheData" + (+ new Date () + ""). slice (-8 );
// (+ New Date (). toString (). slice (-8) is equivalent to expando
// Write Cache
Var data = function (elem, name, value ){
// Or use the native method to verify the String Object. prototype. toString. call (elem) === "[object String]"
// If elem is a string
If (typeof elem = "string "){
// If the name parameter is input, the data is written to the cache.
If (name! = Undefined ){
CacheData [elem] = name;
}
// Return the cached data
Return cacheData [elem];
// If elem is a DOM Node
} Else if (typeof elem = "object "){
Var id,
ThisCache;
// If elem does not have the expando attribute, add an expando attribute (cache the element for the first time). Otherwise, obtain the existing expando and id values directly.
If (! Elem [expando]) {
Id = elem [expando] = ++ uuid;
ThisCache = cacheData [id] = {};
} Else {
Id = elem [expando];
ThisCache = cacheData [id];
}
// Take a random number as an attribute of the current cached object, and use this random number to find the cached object.
If (! ThisCache [expando]) {
ThisCache [expando] = {};
}
If (value! = Undefined ){
// Save the data to the cache object
ThisCache [expando] [name] = value;
}
// Return the data stored by the DOM Element
Return thisCache [expando] [name];
}
};
// Delete Cache
Var removeData = function (elem, name ){
// If elem is a string, the attribute value is deleted directly.
If (typeof elem = "string "){
Delete cacheData [elem];
// If the key is a DOM Node
} Else if (typeof elem = "object "){
// If elem does not have the expando attribute, the execution is terminated without deleting the cache.
If (! Elem [expando]) {
Return;
}
// Check whether the object is empty
Var isEmptyObject = function (obj ){
Var name;
For (name in obj ){
Return false;
}
Return true;
}
RemoveAttr = function (){
Try {
// IE8: The standard browser can directly use delete to delete attributes.
Delete elem [expando];
} Catch (e ){
// IE6/IE7 use removeAttribute to delete attributes
Elem. removeAttribute (expando );
}
},
Id = elem [expando];
If (name ){
// Only delete the specified data
Delete cacheData [id] [expando] [name];
// If it is an empty object, all data objects corresponding to the id are deleted
If (isEmptyObject (cacheData [id] [expando]) {
Delete cacheData [id];
RemoveAttr ();
}
} Else {
// Delete all data stored in the cache by the DOM Element
Delete cacheData [id];
RemoveAttr ();
}
}
};
// Put data and removeData under the window global object, so that the two functions can be accessed externally
Win. expando = expando;
Win. data = data;
Win. removeData = removeData;
}) (Window, undefined );
Example:
HTML structure:Copy codeThe Code is as follows: <div id = "demo" style = "height: 100px; width: 100px; background: # ccc; color: # fff; margin: 20px; text-align: center; line-height: 100px; ">
Demo
</Div>
Js Code:Copy codeThe Code is as follows: window. onload = function (){
// Test
Var demo = document. getElementById ("demo ");
// Write Cache
Data (demo, "myName", "homocysteine ");
Console. log (data (demo, "myName"); // Homocysteine
Data (demo, "myBlog", "http://www.cnblogs.com/cyStyle ");
Console. log (data (demo, "myBlog"); // http://www.cnblogs.com/cyStyle
// Delete a cache value of the DOM Element
RemoveData (demo, "myBlog ");
Console. log (data (demo, "myBlog"); // undefined
Console. log (data (demo, "myName"); // Homocysteine
Console. log (demo [expando]); // 1
// Delete the DOM Element
RemoveData (demo );
Console. log (demo [expando]); // undefined
};
Result of the example in firefox:
To implement jQuery's simple Cache System in the above example: First add a randomly generated attribute expando to the DOM element, which is used to store the id value of the access cache data, just like DOM elements all have a key to enable the cache safe, and you can enable the cache safe at any time if you have a key. The data originally stored in the DOM element is transferred to the cache, And the DOM element itself only needs to store a simple attribute, in this way, the memory leakage caused by DOM elements can be implemented (the specific situation may not be known, as we all say ~) To minimize the risk.
Conclusion
Finally, some terms or explanations may be biased. I hope you can correct your shoes and give some suggestions. In addition, theoretically, the data and removeData methods can be used in the cache of any object. However, if used in a local object or window object, there may be problems such as memory leakage and circular reference (^_^ seen on the Internet ), therefore, it is generally suitable for DOM nodes. You can also use events and animations to cache data on DOM nodes. Ps: cache is really important! Need to learn more ~
Sharing is simple. Sharing is a pleasure.