jQuery1.7系列二: jQuery的緩存機制

           聲明:寫博客,是對自身知識的一種總結,也是一種分享,但由於作者本人水平有限,難免會有一些地方說得不對,還請大家友善  指出,或致電:[email protected]

           關注:國內開源jQuery-UI組件庫:Operamasks-UI

       jQuery版本:v1.7.1


jQuery1.7系列二:  jQuery的緩存機制

一.緩存的基本原理

 

1.      緩存的作用

        在前端的開發中,很多時候需要存儲一些跟dom節點相關的數據,於是jQuery內部實現了一個緩存,用於存儲跟dom節點相關的數據,包括事件,動畫等都會用到。

 

2.      緩存的類別

        jQuery中的緩存可以分爲兩大類別:全局緩存和局部緩存。全局緩存存儲直接與dom節點相關的數據,局部緩存存儲與js對象相關的數據。

 

3.      兩大緩存的實現原理

3.1      全局緩存

         全局緩存定義爲:jQuery.cache = {} ,它就是一個普通的js對象,jQuery暴露了兩個最基本的接口用來與全局緩存進行通信,分別是  jQuery.fn.data 和  jQuery.fn.removeData 。那麼內部是如何實現數據與dom節點一一對應的?先看如下圖:

內部數據與dom節點的一一對應

         當我們第一次執行$(“#div1”).data(“a”, 10)時,jQuery會爲 #div1 這個dom節點添加一個屬性,名字爲expando的計算結果,它是具有唯一性的。然後 expando屬性對應的值 id1 就是該節點在全局緩存$.cache中對應的key了,另外要注意,數據是存儲在data變量中的,它表示這些數據是用戶自己定義的,如果是jQuery核心需要用到的數據,它不會放到data裏邊,而是直接放在“id1”這個key表示的對象下邊。如下圖:

jQuery內部數據的存放

以上便是全局緩存$.cache中的數據存放結構了,而暴露出來的接口不外乎就是進行添加與刪除。

 

3.2      局部緩存

        jQuery源碼中說到,如果是要把數據與js對象(非HTML Node對象)進行關聯,更省事的辦法是直接綁定在對象上,而全局緩存的出現主要是爲了處理IE中內存的泄露問題。我們做一下例子看一看:

 

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type"content="text/html; charset=UTF-8">

<script type="text/javascript"src="jquery-1.7.1.js"></script>

<script>

    $(function(){

       $test = $("#test");

       $.data( $test , "c" , 20);

       console.log("end");

    });

</script>

</head>

<body>

    <div id="test">123</div>

</body>

</html>

代碼非常簡單,我在console.log(“end”)給打上斷點,截圖如下:

局部緩存示例

 

        可以看到,局部緩存是直接存儲在js對象上的,而且放在js對象的expando屬性下邊的data屬性上。

 

二.緩存對html5的屬性支持

        Html5規範中新增了 data-*  這樣的html元素自定義屬性,它可以給頁面創建者本身的腳本進行使用。舉個例子:

<ol>

 <li data-length="2m11s">Beyond The Sea</li>

 ...

</ol>

 

        爲了標識每首歌曲的長度,供用戶排序歌曲時使用,可以添加data-length這樣的自定義屬性,它在本頁面內會使用到。但是data-length 這樣的屬性並不適用於如使用網頁爬蟲這樣的外部程序來使用。

 

       爲了更方便的訪問這一些 data-* 屬性,jQuery內部進行了特殊處理,當我們執行$(“#div1”).data(“a”);這樣的代碼來獲取緩存值時,jQuery會嘗試從全局緩存$.cache來進行查找,如果查找不到值的話,會再嘗試着查找 data-a 這樣的html元素屬性值,接下來我們做個實驗:

 

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type"content="text/html; charset=UTF-8">

<script type="text/javascript"src="jquery-1.7.1.js"></script>

<script>

    $(function(){

       $test = $("#test");

       console.log($test.data("alias"));//會打印出"alias"

    });

</script>

</head>

<body>

    <div id="test" data-alias="alias">123</div>

</body>

</html>

當執行後我們看下結果:

執行結果

在控制檯上確實打印出了“alias” ,說明找到了”alias”屬性。注意,當jQuery從html元素的data-*屬性找到值時,會把值複製到全局緩存$.cache中的。

 

三.緩存與事件

        jQuery在進行緩存事件的操作時,提供了三個事件監聽,分別是 getData, setData和changeData,做一個例子測試一下:

 

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type"content="text/html; charset=UTF-8">

<script type="text/javascript"src="jquery-1.7.1.js"></script>

<script>

    $(function(){

       $test = $("#test");

       $test.bind("getData" ,function(){

           console.log("getData");

       })

       .bind("setData" , function(){

           console.log("setData");

       }).bind("changeData" , function(){

           console.log("changeData");

       });

       $test.data("name" , "xisi");//打印 "setData" "changeData"

       $test.data("name");//打印"getData"

    });

</script>

</head>

<body>

    <div id="test">123</div>

</body>

</html>

cache事件一般用得比較少,估計做一些js組件庫纔會用到吧。


發佈了40 篇原創文章 · 獲贊 174 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章