首先我們來看下簡易備忘錄1.0版本,http://www.reibang.com/p/de7c06a1e924,這版本是根據(jù)上一節(jié)的內(nèi)容改進而成帆阳,上一節(jié)主要講了DOM操作的增刪查改哺壶,但是沒有保存功能和動畫,刷新一下就沒了蜒谤。而這一節(jié)山宾,則是利用localstorage瀏覽器數(shù)據(jù)庫來做,首先我們這一節(jié)主要有以下知識點:
1鳍徽、localstorage的API使用资锰,以及增刪查改。
2阶祭、修改的小坑以及自己的錯誤绷杜。
3、使用動畫的小坑濒募。(精華)
4鞭盟、源碼
首先,國際慣例瑰剃,先看一下效果圖:
localstorage為瀏覽器的存儲齿诉,是HTML5新增的功能,有些同學(xué)可能覺得新出的東西,沒有書籍可以借鑒(這里是舉個例子粤剧,比如HTML5從入門到精通就講了這個歇竟,以及JS大犀牛,也講了這個抵恋。)焕议,如果一門剛出的東西,沒有資料馋记,也沒有博客講解号坡,那么最好的學(xué)習(xí)方法就是看官網(wǎng)啦!Look梯醒!https://developer.mozilla.org/zh-CN/docs/Web/API/Window/localStorage
總結(jié)一下官網(wǎng)的API宽堆,例舉出了以下的屬性:
我們來看常用的方法:
localStorage.setItem('KeyName','Value');//添加
localStorage.removeItem('KeyName');//刪除
localStorage.getItem('keyName');//獲取
for(var i =0; i < localStorage.length; i++){
console.log(localStorage.getItem(localStorage.key(i)));
}//遍歷出所有值
這是增刪查,很遺憾茸习,沒有修改功能。setItem的KeyName和Value是兩個參數(shù)号胚,類似于Java的Map集合籽慢,一個名字一個值,刪除名字猫胁,可以連值一起刪除箱亿。
關(guān)于如何使用localStorage,我們打開瀏覽器弃秆,F(xiàn)12開發(fā)者工具如圖:
我們知道了增刪查的方法之后届惋,再套進自己需要的功能里,于是菠赚,我在代碼里這樣寫:
添加:
//添加方法
function add() {
var input_value = input.value;
localStorage.setItem("Memo" + input_value,input_value);
}
代碼講解:
獲取輸入框的值添加到緩存里脑豹,這里前面加個Memo是為了讓本應(yīng)用和其他應(yīng)用的緩存分別開,但是localstorage好像沒有能過濾Key值的方法衡查,只有一個過濾Value值的localStorage.hasOwnProperty('xxx')方法瘩欺。
刪除:
//刪除方法
function remove(obj) {
localStorage.removeItem("Memo" + obj.previousSibling.data);
obj.parentNode.parentNode.removeChild(obj.parentNode);
}
代碼講解:
這是刪除方法,obj為傳的刪除按鈕拌牲,在我的JS添加的節(jié)點HTML結(jié)構(gòu)中:
<input type='checkbox' class='"+flag+" checkbox' name='check'/>" + localStorage.getItem(item) +
"<button class='btn_remove' onclick='remove(this)'>刪除</button>" +
"<button class='btn_update' onclick='update(this)'>修改</button>";
obj為刪除這個按鈕俱饿,previousSibling為之前的一個兄弟節(jié)點,但是是個對象塌忽,直接拼接是不行的稍途,會顯示[Object Text]這個報錯,所以要加.data才能獲取他的文本砚婆。然后字符串拼接械拍,就可以刪除啦~如圖:
console.log(obj.previousSibling);//"xxx"
console.log("Memo" + obj.previousSibling);//Memo[object Text]
console.log("Memo" + obj.previousSibling.data);//Memoxxx
為什么后面要加.data呢突勇,我們在之前的代碼加了debugger后:
我們看到,鼠標移到這個屬性的時候坷虑,會有個data屬性甲馋,學(xué)過Java的同學(xué)會想到,根據(jù)面向?qū)ο笃穑琾reviousSibling.data就可以拿到值了定躏,嗯,JS也是這樣芹敌。我們?nèi)〉街等叮僮址唇樱涂梢酝瓿衫瞺請注意這里的previousSibling為獲取上一個兄弟節(jié)點氏捞,如果你和HTML結(jié)構(gòu)不同碧聪,請根據(jù)自身代碼進行調(diào)整。
顯示全部液茎,兩種實現(xiàn)方式:
localStorage.valueOf() //顯示全部數(shù)據(jù)
localStorage.key(0) // 根據(jù)下標讀取第N條數(shù)據(jù)
function show_data(){
for(var i = 0;i<localStorage.length;i++){
var content = document.createElement("p");
localStorage.getItem(localStorage.key(i))
main_content.appendChild(content);
}
}
function show_data(){
var content = document.createElement("p");
localStorage.valueOf();
main_content.appendChild(content);
}
二逞姿、修改:
function update(obj){
var f = prompt("請輸入修改的信息",obj.previousSibling.previousSibling.data);
if(f){
localStorage.removeItem("Memo" + obj.previousSibling.previousSibling.data)
localStorage.setItem("Memo" + f ,f);
}else{
return
}
location.reload();
}
之前我的想法是,直接setItem覆蓋捆等,但是反復(fù)運用在一行數(shù)據(jù)上滞造,會變成添加,而且刪除功能會發(fā)生異常(我規(guī)定了格式的栋烤,"Memo" + input_value,input_value谒养,這個可以自己規(guī)定)。因為修改了value的值導(dǎo)致無法刪除明郭。而且我的自定義格式也亂了买窟。
這里的location.reload()則是我代碼里的敗筆,由于之前設(shè)計HTML結(jié)構(gòu)的時候沒考慮周全达址,把紅色提示框放到主體里面去了,以下是錯誤代碼
<div class="main_content" id="main_content">
<p class="main_hint"> 你當前還沒有待辦事項哦!</p>
<!--<p>這里是JS動態(tài)生成的節(jié)點</p>-->
</div>
用了這個HTML結(jié)構(gòu)趁耗,導(dǎo)致無法用局部刷新:
var main_content = document.getElementById("main_content");
content.innerHtml = "";
show_data();
先把內(nèi)容清空沉唠,再使用顯示數(shù)據(jù)方法,便可以達到局部刷新效果苛败÷穑可是因為我HTML結(jié)構(gòu)的不嚴謹,導(dǎo)致需要更改大量代碼罢屈,這就是剛開始設(shè)計沒考慮周全造成的嘀韧。
三、動畫:
//淡入
function show_animation(obj){
var num = 0;
var st = setInterval(function(){
num ++;
obj.style.opacity = num/10;
if(num>=10){
clearInterval(st);
}
},80)
}
//淡出
function hide_animation(obj){
var num = 10;
var st = setInterval(function(){
num --;
obj.style.opacity = num/10;
if(num<=0){
clearInterval(st);
}
},80)
}
這代碼是很常見的JS代碼缠捌,使用setInterval()是因為for循環(huán)不能控制時間锄贷。代碼是沒問題译蒂,但是實際運用,就有問題啦~我們往下看:
然后刪除和添加/顯示所有谊却,套用動畫:
function remove(obj) {
localStorage.removeItem("Memo" + obj.previousSibling.data);
hide_animation(obj.parentNode);
obj.parentNode.parentNode.removeChild(obj.parentNode);
}
這段代碼的理解:代碼從上往下執(zhí)行柔昼,先執(zhí)行刪除緩存,再讓數(shù)據(jù)透明度漸漸消失炎辨,然后再刪除頁面捕透,仔細一看沒什么問題,但是碴萧,透明度調(diào)試乙嘀,是80毫秒一次,那個時候破喻,程序已經(jīng)往下走了虎谢,已經(jīng)刪除了,80毫秒后執(zhí)行透明度淡入低缩,卻已經(jīng)沒這個數(shù)據(jù)了嘉冒,前面加個debugger可以更好地顯示出問題。但是要怎么解決呢咆繁?function remove(obj) {
obj.disabled = true;
localStorage.removeItem("Memo" + obj.previousSibling.data);
hide_animation(obj.parentNode);
}
function hide_animation(obj){
var num = 10;
var st = setInterval(function(){
num --;
obj.style.opacity = num/10;
if(num<=0){
obj.parentNode.removeChild(obj);
clearInterval(st);
}
},80)
}
我們改進了代碼后讳推,因為setInterval是個循環(huán),我們放到循環(huán)里面結(jié)束那里玩般,再執(zhí)行刪除方法银觅,就可以完美搞定啦~hide_animation()方法里是obj.parentNode.removeChild(obj);而不是obj.parentNode.parentNode.removeChild(obj.parentNode);原因是因為此時的obj已經(jīng)是obj.parentNode(參數(shù))了。obj.disabled = true;是為了阻止用戶反復(fù)點擊按鈕而造成報錯坏为。
至于添加的淡入動畫也會出現(xiàn)bug:
代碼如下:
function show_data(){
for(var i = 0;i<localStorage.length;i++){
var content = document.createElement("p");
localStorage.getItem(localStorage.key(i));
show_animation(main_content.appendChild(content));
}
}
function show_animation(obj){
var num = 0;
var st = setInterval(function(){
num ++;
obj.style.opacity = num/10;
if(num>=10){
clearInterval(st);
}
},80)
}
首先究驴,添加會出現(xiàn)閃爍效果,原因就在于那80毫秒匀伏,程序往下走洒忧,文字已經(jīng)加載完了,才執(zhí)行淡入動畫够颠,顯然不行熙侍,于是我們可以這樣改:
function show_data(){
for(var i = 0;i<localStorage.length;i++){
var content = document.createElement("p");
localStorage.getItem(localStorage.key(i))
main_content.appendChild(content);
}
}
function show_animation(obj){
var num = 0;
obj.style.opacity = num;
var st = setInterval(function(){
num ++;
obj.style.opacity = num/10;
if(num>=10){
clearInterval(st);
}
},80)
}
添加一行obj.style.opacity = num;讓它透明度改為0,即可解決該閃爍問題履磨。