localStorage之本地留言板

0. 前言

Web应用的飞速发展,使得客户端存储使用得也越来越多,而实现客户端存储的方式则是多种多样。我在前面也有写到Cookie,最简单而且兼容性最佳的就是Cookie,但是Cookie也有它的缺点。假如我们只是存储一些简单的键值对,那么,我们就可以使用localStorage的方式进行存储,因为,localStorage只要是同源都能访问,那你会不会问什么是同源?同源就是同协议,同域名,同端口。好了,本文主要说的是实现localStorage的留言板功能。


timg.jpg

1. 简介

Web Storage实际上是由两部分组成:sessionStorage与localStorage。

sessionStorage 会话存储
通过window.sessionStorage获得,为每一个同源维持一个独立的存储区域,该存储区域在页面会话期间可用,(即只要浏览器处于打开状态,包括页面重新加载和恢复),只要当会话结束之后(即只要关闭浏览器),数据也就随之销毁了,所以sessionStorage不是一个持久型本地存储,只是一个会话存储。

localStorage 本地存储
通过window.localStorage获得,为每一个同源区维持一个独立的存储区域,但是在浏览器关闭之后,然后重新打开数据仍然存在,可以用于持久型的本地存储,除非你主动删除,否则数据永远不会过期。

与cookie的不同
Web Storage数据完全存储在客户端,不需要通过浏览器的请求将数据传送给服务器,大概在5M左右。
注意
Storage的存储的key和value都是字符串,就算存储对象到value中,默认也会给转换成字符串,该字符串是"[ object object]",如果非要想存储对象的话,而且保留其结构,过后我们获取后可以正常使用的话,我们可以对其存储之前转换成字符串(序列化操作),取出来后,我们再可以转换成对象(反序列化操作)。

2. 代码实现

2.1 留言板的静态页面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            *{
                padding: 0;
                margin: 0;
            }
            #box{
                width: 500px;
                height: 500px;
                margin: 100px auto;
                border: 2px solid darkgreen;
            }
            #msg{
                float: left;
            }
            #msg input:first-of-type{
                width: 390px;
                height: 50px;
                border: 1px solid darkgreen;
                font-size: 30px;
            }
            #msg input:last-of-type{
                width: 100px;
                height: 50px;
                color: white;
                background-color: darkgreen;
                font-size: 30px;
            }
            #clear input{
                width: 200px;
                height: 50px;
                color: white;
                background-color: darkgreen;
                font-size: 30px;
            }
            ul li{
                list-style: none;
                border: 1px solid darkgreen;
            }
            ul li span{
                padding: 15px;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <div id="msg">
                <input type="text" id="msgInput" placeholder="请输入留言" />
                <input type="button" id="msgBtn" value="留言" />
            </div>
            <div id="content">
                <ul></ul>
            </div>
            <div id="clear">
                <input type="button" id="clearAllBtn" value="清空所有" />
            </div>
        </div>
    </body>
</html>
静态页面.png
2.2 留言按钮
var msgBtn = document.querySelector("#msgBtn");
var msgInput = document.querySelector("#msgInput");
var clearAllBtn = document.querySelector("#clearAllBtn");
var msgUl = document.querySelector("ul");
        //留言按钮
        msgBtn.onclick = function () {
            //字符串trim方法,可以去掉字符串前后两端的空格
            //注意:中间的空格不会去掉,这个方法一般用于输入框空格的判断
            var str = msgInput.value.trim(); 
            if ( str != "" && str != null) {
                //留言信息对象
                var msgObj = {
                    value : escape(str),
                    date : new Date().getTime()
                }
                //存储到本地localStorage中
                window.localStorage.setItem("msg_" + msgObj.date,JSON.stringify(msgObj));
    
                //UI
                msgUl.appendChild(createLi(msgObj));
                
                //每次留言过后,清空input
                msgInput.value = "";
            }
        }
        //创建Li
        function createLi(msgObj) {
            var msgLi = document.createElement("li");
            
            //利用li的自定义属性存储这个li对应的数据(key)
            msgLi.setAttribute("key","msg_" + msgObj.date);
            
            var msgSpan = document.createElement("span");
            msgSpan.innerHTML = unescape(msgObj.value);
            var dateSpan = document.createElement("span");
            //先把时间毫秒数转换成日期格式(date),然后转换成字符串
            dateSpan.innerHTML = new Date(msgObj.date).toLocaleString();
            
            msgLi.appendChild(msgSpan);
            msgLi.appendChild(dateSpan);
            
            return msgLi;
            
        }
留言.png

看图片,我们可以看出我们不仅在页面中存储了我的信息,而且在服务器上也存储上了这些信息。

2.3 单个删除留言

在上一个封装的函数中创建删除按钮,实现删除单个留言。

        //创建Li
        function createLi(msgObj) {
            var msgLi = document.createElement("li");
            
            //利用li的自定义属性存储这个li对应的数据(key)
            msgLi.setAttribute("key","msg_" + msgObj.date);
            
            var msgSpan = document.createElement("span");
            msgSpan.innerHTML = unescape(msgObj.value);
            var dateSpan = document.createElement("span");
            //先把时间毫秒数转换成日期格式(date),然后转换成字符串
            dateSpan.innerHTML = new Date(msgObj.date).toLocaleString();
            
            //删除单个留言按钮   
            var delBtn = document.createElement("input");
            delBtn.type = "button";
            delBtn.value ="X";
    
            msgLi.appendChild(msgSpan);
            msgLi.appendChild(dateSpan);
            msgLi.appendChild(delBtn);
        
            return msgLi;
            
        }
        //利用事件委托给Ul添加点击事件    单个删除留言
        msgUl.onclick = function (e) {
            if (e.target.nodeName == "INPUT") {
                //删除本地存储中的键值对
                window.localStorage.removeItem(e.target.parentNode.getAttribute("key"));
                
                //删除页面上li
                this.removeChild(e.target.parentNode);
            }
        }
删除单个留言.gif

看图,我先添加一些信息,然后我在点击X号的时候,在本地存储的和页面上的都被删除了。

2.4 清空所有
        //清空所有
        clearAllBtn.onclick = function () {
            
            //数据清空 本地留言相关 存储
            var liArr = document.querySelectorAll("li");
            for (var key in window.localStorage) {
                for (var i = 0; i < liArr.length; i++) {
                    if (liArr[i].getAttribute("key") == key) {
                        window.localStorage.removeItem(key);
                    }
                }
            }
                
            //页面清空
            msgUl.innerHTML = "";
            
        }
删除所有.gif

在我点击删除所有的时候,不管是在本地的还是在页面上的都被删除了。

2.5 显示所有信息
//显示所有留言信息的功能
        function showMsgInfos() {
            var keyRegExp = /^(msg_)/;
            for (var key in window.localStorage) {
                if (keyRegExp.test(key)) {
                    console.log(window.localStorage.getItem(key))
                    console.log(JSON.parse(window.localStorage.getItem(key)))
                    msgUl.appendChild(createLi(JSON.parse(window.localStorage.getItem(key))));
                }
            }
        }
        showMsgInfos();
显示所有信息.png

这个功能我给你展示不了了,就是你存入几条信息,关闭浏览器,然后在打开,那些信息,还会有,当然,在本地里也会有,就证明了localStore的数据持久型的特点,除非你主动删除,否则永远不会过期。

3. 完整代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            *{
                padding: 0;
                margin: 0;
            }
            #box{
                width: 500px;
                height: 500px;
                margin: 100px auto;
                border: 2px solid darkgreen;
            }
            #msg{
                float: left;
            }
            #msg input:first-of-type{
                width: 390px;
                height: 50px;
                border: 1px solid darkgreen;
                font-size: 30px;
            }
            #msg input:last-of-type{
                width: 100px;
                height: 50px;
                color: white;
                background-color: darkgreen;
                font-size: 30px;
            }
            #clear input{
                width: 200px;
                height: 50px;
                color: white;
                background-color: darkgreen;
                font-size: 30px;
            }
            ul li{
                list-style: none;
                border: 1px solid darkgreen;
            }
            ul li span{
                padding: 15px;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <div id="msg">
                <input type="text" id="msgInput" placeholder="请输入留言" />
                <input type="button" id="msgBtn" value="留言" />
            </div>
            <div id="content">
                <ul></ul>
            </div>
            <div id="clear">
                <input type="button" id="clearAllBtn" value="清空所有" />
            </div>
        </div>
        <script type="text/javascript">
        var msgInput = document.querySelector("#msgInput");
        var msgBtn = document.querySelector("#msgBtn");
        var clearAllBtn = document.querySelector("#clearAllBtn");
        var msgUl = document.querySelector("ul");
        
        //留言按钮
        msgBtn.onclick = function () {
            //字符串trim方法,可以去掉字符串前后两端的空格
            //注意:中间的空格不会去掉,这个方法一般用于输入框空格的判断
            var str = msgInput.value.trim(); 
            if ( str != "" && str != null) {
                //留言信息对象
                var msgObj = {
                    value : escape(str),
                    date : new Date().getTime()
                }
                console.log(msgObj);
                console.log(JSON.stringify(msgObj));
                //存储到本地localStorage中
                window.localStorage.setItem("msg_" + msgObj.date,JSON.stringify(msgObj));
                
                //UI
                msgUl.appendChild(createLi(msgObj));
                
                //每次留言过后,清空input
                msgInput.value = "";
            }
        }
        
        //创建Li
        function createLi(msgObj) {
            var msgLi = document.createElement("li");
            
            //利用li的自定义属性存储这个li对应的数据(key)
            msgLi.setAttribute("key","msg_" + msgObj.date);
            
            var msgSpan = document.createElement("span");
            msgSpan.innerHTML = unescape(msgObj.value);
            var dateSpan = document.createElement("span");
            //先把时间毫秒数转换成日期格式(date),然后转换成字符串
            dateSpan.innerHTML = new Date(msgObj.date).toLocaleString();
            
            //删除单个留言按钮
            var delBtn = document.createElement("input");
            delBtn.type = "button";
            delBtn.value ="X";
            
            msgLi.appendChild(msgSpan);
            msgLi.appendChild(dateSpan);
            msgLi.appendChild(delBtn);
            
            return msgLi;
            
        }
        
        
        //单个删除留言
        msgUl.onclick = function (e) {
            if (e.target.nodeName == "INPUT") {
                //删除本地存储中的键值对
                window.localStorage.removeItem(e.target.parentNode.getAttribute("key"));
                
                //删除页面上li
                this.removeChild(e.target.parentNode);
            }
        }
        
        //清空所有
        clearAllBtn.onclick = function () {
            
            //数据清空 本地留言相关 存储
            var liArr = document.querySelectorAll("li");
            for (var key in window.localStorage) {
                for (var i = 0; i < liArr.length; i++) {
                    if (liArr[i].getAttribute("key") == key) {
                        window.localStorage.removeItem(key);
                    }
                }
            }
                
            //页面清空
            msgUl.innerHTML = "";
            
        }
        
        //显示所有留言信息的功能
        function showMsgInfos() {
            var keyRegExp = /^(msg_)/;
            for (var key in window.localStorage) {
                if (keyRegExp.test(key)) {
                    msgUl.appendChild(createLi(JSON.parse(window.localStorage.getItem(key))));
                }
            }
        }
        showMsgInfos();
        </script>
    </body>
</html>

4. 后记

对于这些存储的了解,我可能理解的不是很好,如果你发现我哪里写错了,请你留言告诉我,最后,留下你的脚印,点个赞,分享一下!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容