国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

localStorage實現本地儲存樹形菜單

William_Sang / 2710人閱讀

摘要:因為任務需要添加到樹的結構上,所以要記錄任務是添加到哪個結點上的,需要為每個樹結點添加一個作為標識以便于在結點上添加任務,樹狀結構中每個結點的按照樹的先序遍歷將結點的依次儲存于數組中。

localStorage實現本地儲存樹形菜單

最近在寫一個Todo-list的頁面,頁面布局和操作都寫完后,想要用localStorage實現本地儲存。然而對儲存數據的方法一無所知,就先去了解了web的數據儲存。

數據儲存

常用的web的數據儲存有cookie和Web Storage儲存機制。

cookie

cookie是“小型文本文件”,主要用途是辨別用戶身份、保存用戶登錄信息。cooki是由服務器端生成、儲存在客戶端上的數據(通常經過加密)。

Cookie會被附加在每個HTTP請求中,所以無形中增加了流量。

HTTP請求中的Cookie是明文傳遞的,安全性成問題。(除非用HTTPS)

Cookie的大小限制在4KB左右。于復雜的存儲需求來說是不夠用的。

Web Storage

Web Storage定義了兩種儲存數據的對象,localStorage和sessionStorage,它們儲存大小一般為5MB,機制如下:

sessionStorage由瀏覽器存儲某個會話(browsing session)的數據,數據在當前會話下有效,刷新頁面數據依舊存在,但在關閉頁面或瀏覽器后被清除。

localStorage由瀏覽器存儲數據,數據沒有過期時間(expiration time),也就是瀏覽器關閉再重新打開后數據仍然存在。

localStorage對象的操作

在存儲中設置值:Storage.setItem()
從存儲中獲取值:Storage.getItem()
響應存儲的變化:window.addEventListener("storage", function(e){});
刪除數據記錄:Storage.removeItem() 接受一個參數——你想要移除的數據項的鍵,然后會將對應的數據項從域名對應的存儲對象中移除。Storage.clear() 不接受參數,只是簡單地清空域名對應的整個存儲對象。

樹形菜單的數據儲存

在我的todo-list頁面中,用戶對樹的操作有:

在樹形菜單上添加、刪除任務分類

在任務分類中添加、刪除該分類中的任務。
也是是說用戶的每次操作后都要更新存儲的數據,以便在刷新頁面后顯示出用戶操作后更改過的頁面。

由于本地儲存只能存字符串數據,所以存儲屬性菜單可以用到JSON。用JSON.parse將一個JavaScript對象字符串化為JSON,然后整個存入localStorage來實現保存。用JSON.stringify將JSON字符串解析成為一個JavaScript對象來從存儲中獲取值。
那么怎么用對象存儲樹形菜單呢,我想到了兩個方式。

方式一

一種是用一個對象treeframe存儲樹的結構(所有的任務分類,不包括分類中的任務)以及樹結點中的任務,存儲形式如下。一旦對樹形菜單執行任何一項操作,就更新treeframe對象。

var treeframe = {
    "任務列表":{
        "使用說明":[
            {
                "title":"普通任務列表",
                "content":"可以設定任務的名稱、任務描述、任務截止時間",
                "endTime":"2016-05-20",
                "type":"normal",
            },
            {
                "title":"添加新分類",
                "content":"通過左側自定義分類的文件夾圖標添加新分類",
                "endTime":"2017-07-20",
                "type":"normal",
            }
        ],
        "今日任務":{},
        "短期任務":{
            "7月":{},
            "8月":{},
            "9月":{}
        },
        "長期任務":{}
     }
}
方式二

另一種方式是用一個對象treeframe存儲樹的結構,還有一個對象allTasks存儲所有結點中的任務。這種方式只需要在添加、刪除任務分類時更新樹的結構treeframe;添加、刪除任務時更改allTasks。因為任務需要添加到樹的結構上,所以要記錄任務是添加到哪個結點上的,需要為每個樹結點添加一個id作為標識以便于在結點上添加任務,樹狀結構中每個結點的id按照樹的先序遍歷將結點的id依次儲存于數組treeClassify.list中。為了每一個新增的結點的id都不與已存在的id的結點相同,用一個計數器fatherIdjsq來記錄可添加的新id。
存儲形式如下:

var treeframe = {
    "任務列表":{
        "使用說明":{},
        "今日任務":{},
        "短期任務":{
            "7月":{},
            "8月":{},
            "9月":{}
        },
        "長期任務":{}
     }
}

var allTasks = {
    "list" : [    {
                "fatherId":"fatherId1"
                "title":"普通任務列表",
                "cnode":{"value":"普通任務列表"},
                "pnode":{"value":"使用說明"},
                "content":"可以設定任務的名稱、任務描述、任務截止時間",
                "endTime":"2016-05-20",
                "type":"normal",
            },
            {
                "fatherId":"fatherId5"
                "title":"添加新分類",
                "cnode":{"value":"添加新分類"},
                "pnode":{"value":"使用說明"},
                "content":"通過左側自定義分類的文件夾圖標添加新分類",
                "endTime":"2017-07-20",
                "type":"fast",
            }]
};
var treeClassfiy = {"list":["fatherId0","fatherId1","fatherId2","fatherId3","fatherId4","fatherId5","fatherId6","fatherId8","fatherId7"]}
var fatherIdjsq = 9

我覺得如果最開始寫整個todo-list時對整個頁面的功能和操作以及邏輯都理的特別清楚的話,第一種存儲方法一定用起來更加方便。但是我選了第二種,因為這樣便于我分別對樹的結構和任務列表進行操作,和我之前寫好的代碼比較容易融合在一起。
所以最終要存儲的數據如下:

- 樹狀結構的存儲:對象字面量形式與json的相互轉化
- 樹狀結構中每個結點的id:按照樹的先序遍歷將結點的id依次儲存于數組中
- 所有任務:每一個任務存儲于一個對象中,所有任務的對象組成一個數組
- 可以添加的新id
樹形菜單的操作與儲存 1. 刪除任務分類

更改樹狀結構,在界面上刪除這個分類的后,將這個分類的id從存儲id的數組中刪去。

var jsq = 0;                                                      //計數器jsq用來記錄按先序遍歷樹,并將結點存于數組時,該結點在數組中的位置
preOrder(treedata);                                               //先序遍歷treeframe(treeframe初始儲存于treedata)
function preOrder(treeframe) {
    for(var key in treeframe) {
        if(jsq===fatherIdArr.indexOf(choseDiv.id)) {              //查找到當前要刪除的結點(通過查看當前要刪除結點的id在儲存結點id的數組(treeClassfiy.list)中的位置)
            delete treeframe[key];                                   //通過detele刪除對象的屬性來刪除結點
            var pos = treeClassifyIdArr.list.indexOf(choseDiv.id);//查找當前要刪除的結點id在儲存結點id的數組中(treeClassfiy.list)的位置
            treeClassifyIdArr.list.splice(pos,1);                  //把id從數組中刪除
            fatherIdArr.splice(jsq, 1);
            break;
        }
        jsq++;
        if(typeof treeframe[key] === "object") {
            preOrder(treeframe[key]);
        }
    }
}
localStorage.setItem("treeframe", JSON.stringify(treedata));      //將更新的treedata存入設置的值treeframe中
2. 添加任務分類

每次手動添加任務分類時,樹狀結構會改變。也就是說樹狀結構的改變,意味著樹的結點增加/刪除了,存儲結點id的數組也要改變。
所以要更改樹狀結構,為新添的分類設置一個新的id,在界面上創建這個分類的后,將這個分類的id插入到存儲id的數組中。

var jsq = 0;
preOrder(treedata);
function preOrder(treeframe) {
    for(var key in treeframe) {
        if(jsq===fatherIdArr.indexOf(choseDiv.id)) {             //找到被選中的結點
            fatherIdArr.push("fatherId"+fatherIdjsq);            //先在數組中添加新的id,使新的結點渲染到頁面上
            treeframe[key][value] = {};                          //更新樹狀結構,添加結點(為記錄樹的結構的對象添加屬性)
            preOrder2(treeframe[key]);
            function preOrder2(treeframe) {                      //jsq記錄被選中結點的的最后一個子節點
                for(var key in treeframe) {
                    jsq++;
                    if(typeof treeframe[key] === "object") {
                        preOrder2(treeframe[key]);
                    }
                }
            }
            break;
        }
        jsq++;
        if(typeof treeframe[key] === "object") {
            preOrder(treeframe[key]);
        }
    }
}
localStorage.setItem("treeframe", JSON.stringify(treedata));     //將更新的treedata存入設置的值treeframe中
/*此處渲染頁面*/ 
fatherIdArr.pop();                                               //新的結點渲染到頁面上后刪除該結點的id
fatherIdArr.splice(jsq, 0, "fatherId"+fatherIdjsq++);            //更新該結點id在id數組中的位置
treeClassifyIdArr.list = [];                                     //將id數組中的元素添加到對象中
for(var j=0;j
3. 刪除任務
tasklistArr.splice(i,1);
allTasks.list = [];
for(var j=0;j
4. 添加任務
allTasks.list = [];
for(var i=0;i
5. 測試本地存儲是否已被填充
if(!localStorage.getItem("treeClassify")) {
//本地沒有存儲,加載初始設置的頁面
} else {
//本地有存儲,不加載初始設置的頁面,而是根據儲存來渲染頁面
}
所有存儲操作的封裝
var Storage = (function(mod) {
    // 刪除、添加、編輯快速任務和普通任務的存儲
    mod.TaskChange = function() {
        allTasks.list = [];
        for(var i=0;i
需要注意的地方

加載初始設置的頁面的過程中,不需要存儲任何數據,也就是不需要操作localStorage對象。這樣的話如果用戶不對頁面進行操作,就沒有任何數據需要存儲。只有在用戶對頁面進行操作后,才會儲存并再頁面再次刷新時按照儲存的內容進行頁面的渲染。

在線查看demo

在線demo可供參考,歡迎review代碼,求批評、建議和交流:p
localStorage實現本地儲存樹形菜單_demo

參考資料

詳說 Cookie, LocalStorage 與 SessionStorage
JSON.stringify
鏈使用 Web Storage API

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86455.html

相關文章

  • 前端面試之htm5新特性

    摘要:今天來談談前端面試中基本上每次一面的時候都會被問到的一個問題,那就是的新特性。新表單元素元素,表示電話號碼。和通過設置和特性,可以將輸入框的數值輸入范圍限定在最低值和最高值之間。一旦為某輸入型控件設置了特性,那么此項必填,否則無法提交表單。 今天來談談前端面試中基本上每次一面的時候都會被問到的一個問題,那就是html5的新特性。這個是學習前端必須掌握的基礎知識。 新增的元素 html5...

    teren 評論0 收藏0
  • htm5新特性(轉)

    摘要:轉自今天來談談前端面試中基本上每次一面都會被問到的一個問題,那就是的新特性了。元素,表示生成密匙。和通過設置和特性,可以將輸入框的數值輸入范圍限定在最低值和最高值之間。一旦為某輸入型控件設置了特性,那么此項必填,否則無法提交表單。 轉自:http://hyuhan.com/2017/07/06/... 今天來談談前端面試中基本上每次一面都會被問到的一個問題,那就是html5的新特性了。...

    focusj 評論0 收藏0
  • Chrome擴展程序開發

    摘要:這一步可以參考應用商店上傳擴展程序一文最后終于搞定,線上可見學習資源建立擴展程序插件開發攻略如何成為一名應用開發者擴展的開發下一步插件功能豐富化插件可在網頁上高亮展示標記的文本用重構需要使用框架嗎注本文源碼位于倉庫,線上產品見和 十一在家無聊時開發了這個項目。其出發點是想通過chrome插件,來保存網頁上選中的文本。后來就順手把前后端都做了(Koa2 + React): chrome...

    dinfer 評論0 收藏0
  • 利用localStorage本地儲存js文件

    摘要:通過采用同步的形式獲取內容,取得內容后,執行文件的內容,設置保存到中,再刪除中上個版本的文件。同步獲取文件內容。 利用localStorage儲存js文件,只有在第一次訪問該頁面的時候加載js文件,以后在訪問的時候加載本地localStorage執行 封裝lsFile類 有url、filename(key前綴)、lname(key)、filetext(值)屬性 var lstora...

    haitiancoder 評論0 收藏0

發表評論

0條評論

William_Sang

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<