最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

jQuery數(shù)據(jù)緩存功能的實(shí)現(xiàn)思路及簡(jiǎn)單模擬

 更新時(shí)間:2013年05月27日 16:12:31   作者:  
jQuery緩存系統(tǒng)不僅運(yùn)用于DOM元素,動(dòng)畫、事件等都有用到這個(gè)緩存系統(tǒng)
前言
對(duì)于jQuery的數(shù)據(jù)緩存,相信大家都不會(huì)陌生,jQuery緩存系統(tǒng)不僅運(yùn)用于DOM元素,動(dòng)畫、事件等都有用到這個(gè)緩存系統(tǒng)。所以在平時(shí)實(shí)際應(yīng)用中, 我們經(jīng)常需要給元素緩存一些數(shù)據(jù),并且這些數(shù)據(jù)往往和DOM元素緊密相關(guān)。由于DOM元素(節(jié)點(diǎn))也是對(duì)象, 所以我們可以直接擴(kuò)展DOM元素的屬性,但是如果給DOM元素添加自定義的屬性和過多的數(shù)據(jù)可能會(huì)引起內(nèi)存泄漏,所以應(yīng)該要盡量避免這樣做。 因此更好的解決方法是使用一種低耦合的方式讓DOM和緩存數(shù)據(jù)能夠聯(lián)系起來。

另外:對(duì)于jQuery.data和jQuery.removeData靜態(tài)方法、以及基于這兩個(gè)方法的原型擴(kuò)展方法的介紹和用法就不多說了,可以查看官方API文檔。

實(shí)現(xiàn)思路
jQuery提供了一套靈活和強(qiáng)大的緩存方法:
(1)先在jQuery內(nèi)部創(chuàng)建一個(gè)cache對(duì)象{}, 來保存緩存數(shù)據(jù)。 然后往需要進(jìn)行緩存的DOM節(jié)點(diǎn)上擴(kuò)展一個(gè)值為expando的屬性, 這里是”jQuery” + (new Date).getTime()。 注:expando的值等于”jQuery”+當(dāng)前時(shí)間, 元素本身具有這種屬性的可能性很少,所以可以忽略沖突。
(2)接著把每個(gè)節(jié)點(diǎn)的dom[expando]的值都設(shè)為一個(gè)自增的變量id,保持全局唯一性。 這個(gè)id的值就作為cache的key用來關(guān)聯(lián)DOM節(jié)點(diǎn)和數(shù)據(jù)。也就是說cache[id]就取到了這個(gè)節(jié)點(diǎn)上的所有緩存,即id就好比是打開一個(gè)房間(DOM節(jié)點(diǎn))的鑰匙。 而每個(gè)元素的所有緩存都被放到了一個(gè)map映射里面,這樣可以同時(shí)緩存多個(gè)數(shù)據(jù)。
(3)所以cache對(duì)象結(jié)構(gòu)應(yīng)該像下面這樣:
復(fù)制代碼 代碼如下:

var cache = {
"uuid1": { // DOM節(jié)點(diǎn)1緩存數(shù)據(jù),"uuid1"相當(dāng)于dom1[expando]
"name1": value1,
"name2": value2
},
"uuid2": { // DOM節(jié)點(diǎn)2緩存數(shù)據(jù),“uuid2"相當(dāng)于dom2[expando]
"name1": value1,
"name2": value2
}
// ......
};

每個(gè)uuid對(duì)應(yīng)一個(gè)elem緩存數(shù)據(jù),每個(gè)緩存對(duì)象是可以由多個(gè)name/value(名值對(duì))對(duì)組成的,而value是可以是任何數(shù)據(jù)類型的。

簡(jiǎn)單模擬實(shí)現(xiàn)
根據(jù)以上思路,就可以簡(jiǎn)單實(shí)現(xiàn)下jQuery.data和jQuery.removeDate的功能了:
復(fù)制代碼 代碼如下:

(function(window, undefined) {
var cacheData = {}, // 用來存儲(chǔ)數(shù)據(jù)的對(duì)象
win = window, // 把window緩存給一個(gè)變量
uuid = 0,
// 聲明隨機(jī)數(shù)(8位)
// 注意+new Date()生成的隨機(jī)數(shù)是Number類型,與一個(gè)空字符串連接后(或使用toString方法轉(zhuǎn)型后)變成字符串,才可使用slice方法。
expando = "cacheData" + (+new Date() + "").slice(-8);
// (+new Date()).toString().slice(-8)等價(jià)于expando
// 寫入緩存
var data = function(elem, name, value) {
// 或使用原生方法驗(yàn)證字符串Object.prototype.toString.call(elem) === "[object String]"
// 如果elem為字符串
if (typeof elem === "string") {
// 如果傳入name參數(shù),則為寫入緩存
if (name !== undefined) {
cacheData[elem] = name;
}
// 返回緩存數(shù)據(jù)
return cacheData[elem];
// 如果elem為DOM節(jié)點(diǎn)
} else if (typeof elem === "object") {
var id,
thisCache;
// 如果elem不存在expando屬性,則添加一個(gè)expando屬性(第一次給元素設(shè)置緩存),否則直接獲取已有的expando和id值
if (!elem[expando]) {
id = elem[expando] = ++uuid;
thisCache = cacheData[id] = {};
} else {
id = elem[expando];
thisCache = cacheData[id];
}
// 把一個(gè)隨機(jī)數(shù)作為當(dāng)前緩存對(duì)象的一個(gè)屬性,利用該隨機(jī)數(shù)就能找到該緩存對(duì)象
if (!thisCache[expando]) {
thisCache[expando] = {};
}
if (value !== undefined) {
// 將數(shù)據(jù)存到緩存對(duì)象中
thisCache[expando][name] = value;
}
// 返回DOM元素存儲(chǔ)的數(shù)據(jù)
return thisCache[expando][name];
}
};
// 刪除緩存
var removeData = function(elem, name) {
// 如果elem為字符串,則直接刪除該屬性值
if (typeof elem === "string") {
delete cacheData[elem];
// 如果key為DOM節(jié)點(diǎn)
} else if (typeof elem === "object") {
// 如果elem不存在expando屬性,則終止執(zhí)行,不用刪除緩存
if (!elem[expando]) {
return;
}
// 檢測(cè)對(duì)象是否為空
var isEmptyObject = function(obj) {
var name;
for (name in obj) {
return false;
}
return true;
}
removeAttr = function() {
try {
// IE8即標(biāo)準(zhǔn)瀏覽器可以直接使用delete來刪除屬性
delete elem[expando];
} catch (e) {
// IE6/IE7使用removeAttribute方法來刪除屬性
elem.removeAttribute(expando);
}
},
id = elem[expando];
if (name) {
// 只刪除指定的數(shù)據(jù)
delete cacheData[id][expando][name];
// 如果是空對(duì)象,id所對(duì)應(yīng)的數(shù)據(jù)對(duì)象全部刪除
if (isEmptyObject(cacheData[id][expando])) {
delete cacheData[id];
removeAttr();
}
} else {
// 刪除DOM元素存到緩存中的所有數(shù)據(jù)
delete cacheData[id];
removeAttr();
}
}
};
// 把data和removeData掛在window全局對(duì)象下,這樣在外部也能訪問到這兩個(gè)函數(shù)
win.expando = expando;
win.data = data;
win.removeData = removeData;
})(window, undefined);

例子:
HTML結(jié)構(gòu):
復(fù)制代碼 代碼如下:

<div id="demo" style="height: 100px; width: 100px; background: #ccc; color: #fff; margin: 20px; text-align: center; line-height: 100px;">
demo
</div>

js代碼:
復(fù)制代碼 代碼如下:

window.onload = function() {
// 測(cè)試
var demo = document.getElementById("demo");
// 寫入緩存
data(demo, "myName", "hcy");
console.log(data(demo, "myName")); // hcy
data(demo, "myBlog", "http://www.cnblogs.com/cyStyle");
console.log(data(demo, "myBlog")); // http://www.cnblogs.com/cyStyle
// 刪除DOM元素的某個(gè)緩存值
removeData(demo, "myBlog");
console.log(data(demo, "myBlog")); // undefined
console.log(data(demo, "myName")); // hcy
console.log(demo[expando]); // 1
// 刪除DOM元素
removeData(demo);
console.log(demo[expando]); // undefined
};

firefox下例子結(jié)果截圖:
 
對(duì)于上述例子實(shí)現(xiàn)jQuery的簡(jiǎn)單緩存系統(tǒng):先給該DOM元素添加一個(gè)隨機(jī)生成的屬性expando,這個(gè)屬性用來存放訪問緩存數(shù)據(jù)的id值,就好比DOM元素都有一把開啟緩存保險(xiǎn)箱的鑰匙,只要有了鑰匙就可以隨時(shí)開啟緩存保險(xiǎn)箱。 將本來存放到DOM元素中的數(shù)據(jù)都轉(zhuǎn)到了緩存中,而DOM元素本身只要存儲(chǔ)一個(gè)簡(jiǎn)單的屬性就可以了,這樣就可以將由DOM元素引起的內(nèi)存泄漏(具體會(huì)發(fā)生什么狀況不知道,大家都這么說~)的風(fēng)險(xiǎn)規(guī)避到最小。

結(jié)語
糊里糊涂地又到了最后,有一些術(shù)語或解釋上可能存在偏差,望各位童鞋指正和給出一些建議;另外,從理論上講, data和removeData方法可以用于任何對(duì)象的緩存, 不過如果運(yùn)用于本地對(duì)象或window對(duì)象, 會(huì)存在內(nèi)存泄露、循環(huán)引用等問題(^_^從網(wǎng)上看到的), 所以一般還是用于DOM節(jié)點(diǎn)比較適合,還可以結(jié)合事件、動(dòng)畫對(duì)DOM節(jié)點(diǎn)進(jìn)行緩存數(shù)據(jù)的操作。ps:cache真的很重要!需要慢慢體會(huì)~
因?yàn)榉窒?,所以?jiǎn)單;因?yàn)榉窒恚钥鞓贰?

相關(guān)文章

  • jQuery多級(jí)手風(fēng)琴菜單實(shí)例講解

    jQuery多級(jí)手風(fēng)琴菜單實(shí)例講解

    這篇文章主要介紹了jQuery實(shí)現(xiàn)多級(jí)手風(fēng)琴菜單,菜單效果更有特色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-10-10
  • 分享一款基于jQuery的視頻播放插件

    分享一款基于jQuery的視頻播放插件

    最近在做一個(gè)項(xiàng)目,需要一個(gè)在線視頻播放的功能,在度娘上找了許多都不是太理想,就動(dòng)手寫了一個(gè),分享給大家
    2014-10-10
  • 基于jQuery實(shí)現(xiàn)彈幕APP

    基于jQuery實(shí)現(xiàn)彈幕APP

    這篇文章主要為大家詳細(xì)介紹了基于jQuery實(shí)現(xiàn)彈幕APP的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • jQuery實(shí)現(xiàn)在最后一個(gè)元素之前插入新元素的方法

    jQuery實(shí)現(xiàn)在最后一個(gè)元素之前插入新元素的方法

    這篇文章主要介紹了jQuery實(shí)現(xiàn)在最后一個(gè)元素之前插入新元素的方法,涉及jquery針對(duì)頁面元素的匹配選擇與屬性操作相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • 基于jQuery實(shí)現(xiàn)文本框縮放以及上下移動(dòng)功能

    基于jQuery實(shí)現(xiàn)文本框縮放以及上下移動(dòng)功能

    這里給大家分享一段個(gè)人覺著非常實(shí)用也經(jīng)常用于項(xiàng)目中的代碼,本代碼基于jQuery實(shí)現(xiàn)了文本框縮放以及上下移動(dòng)功能,給需要的網(wǎng)友們參考下吧
    2014-11-11
  • JQuery 1.3.2以上版本中出現(xiàn)pareseerror錯(cuò)誤的解決方法

    JQuery 1.3.2以上版本中出現(xiàn)pareseerror錯(cuò)誤的解決方法

    最近正在做一個(gè)系統(tǒng),測(cè)試組那邊不停的報(bào)告bug:后臺(tái)、前臺(tái)各種列表報(bào)告js彈出窗錯(cuò)誤,內(nèi)容僅僅是一句“pareseerror”!
    2011-01-01
  • Jquery仿IGoogle實(shí)現(xiàn)可拖動(dòng)窗口示例代碼

    Jquery仿IGoogle實(shí)現(xiàn)可拖動(dòng)窗口示例代碼

    這個(gè)拖動(dòng)窗口是根據(jù)一個(gè)Jquery的框架直接做出來的:easywidgets,廢話就不多說了,直接把源代碼貼出來,讓大家學(xué)習(xí)
    2014-08-08
  • jQuery實(shí)現(xiàn)增刪改查

    jQuery實(shí)現(xiàn)增刪改查

    這篇文章主要為大家詳細(xì)介紹了jQuery實(shí)現(xiàn)增刪改查,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • jQuery 全選 全部選 反選 實(shí)現(xiàn)代碼

    jQuery 全選 全部選 反選 實(shí)現(xiàn)代碼

    上次做了一個(gè)前端項(xiàng)目,其中有功能要求實(shí)現(xiàn)jquery 全選和反選功能,下面小編抽個(gè)時(shí)間把實(shí)現(xiàn)代碼分享到腳本之家平臺(tái)供大家參考下
    2016-08-08
  • jQuery樣式操作方法整理介紹

    jQuery樣式操作方法整理介紹

    這篇文章主要介紹了jQuery樣式操作方法,并通過實(shí)際案例更淺顯的理解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10

最新評(píng)論

缙云县| 从化市| 孙吴县| 修武县| 于都县| 通州区| 南宫市| 普安县| 广德县| 巴楚县| 中江县| 台湾省| 博湖县| 安福县| 疏附县| 都匀市| 伊通| 洮南市| 永新县| 保康县| 湘潭市| 会东县| 庆云县| 五大连池市| 承德市| 航空| 长宁县| 莱芜市| 东兴市| 肥城市| 鲜城| 南京市| 平邑县| 宕昌县| 三门县| 揭东县| 裕民县| 志丹县| 池州市| 龙南县| 新建县|