放寒假了,整日昏昏欲睡,实在无聊。今天看了一会书,忽然发现一个让自己感兴趣的玩意——HTML5 localStorage,于是花了一下午加半晚上的时间完成了这个应用。
很多该说的,该写的已经在源码里了。相信大家都和我一样,喜欢看源码。源码来的直接一点。遂奉上源码,当然还有整个项目的百度网盘地址,由于只使用了3张很小的图片,遂整个应用显的很苗条,压缩之后只剩下156KB了。
应用地址:http://liyaodong.sinaapp.com/localStorage/
百度网盘源码下载:http://pan.baidu.com/share/link?shareid=249047&uk=3171893396
Tip:源码下来后直接是看不到效果的,localStorage需要服务器的支持。wamp搭建个临时的吧。
技术难点分析:
首先就是localStorage了,localStorage就是一个基于客户端的数据库吧,可以这么说。但是这个数据库只能放点不是很重要的玩意,如果你放进去账号密码。那么再删除浏览器或者更换浏览器或者清空缓存或者重装系统之后,恭喜你,你就杯具了。localStorage允许我们在客户端,即浏览器内存储5MB的数据。神马?才5MB?太小气了吧。起初我也这么认为,但是当我支持Cookies只支持4K之后我突然觉得HTML5已经很大方了。毕竟是客户端嘛,相对于Cookies来说,localStorage有更大的空间,更长的生命周期。可以存储更多的东西,这会使你的应用看起来更像应用一点。不是吗?
那么localStorage到底怎么看呢?打开你的Chrome,不要给我说你还在用IE6,请使用支持HTML5的浏览器,例如Chrome、Safari、猎豹、360急速、搜狗等国产浏览器的急速模式。也就是webkit,因为我没有针对火狐和IE这2B做优化。所以应该是看不了的,推荐使用webkit内核的浏览器查看。如果你确定是webkit内核了,请按F12,打开审查元素,点击Resources看左侧的Local Storage,选中你查看的网站的域就可以了。需要注意的是localStorage需要有服务器的支持,没有服务器的亲可以下载wamp或者phpnow之类的。
如果你在即时贴中输入数据就可以看到localStorage中有数据了。
难点二就是让颜色随机的很好看了,这个是通过控制HSL颜色模式中的H来达到目的的,HSL和RGB、HSB一样都是一种颜色模式,而且CSS原生支持HSL,起初我还在为RGB转HSB的公式而头疼,我这人不喜欢数学。但是RGB转HSB的公式让我想起了我蛋疼的高数。正在沮丧之时我看到CSS的手册中颜色模式有HSL,就差一个B,估计也2不到哪去。然后研究了一下发现HSL和HSB很像,但只是很像,具体区别请找度娘。
难点三呢就是没有了,其他的CSS、响应式WEB都不算难点,因为写JS是最花时间和脑细胞的。看起来就会觉得头疼。不是吗?
下面不废话了,奉上源码,给不能再百度网盘下载源码的亲们,希望大家寒假都能有所收获:
HTML源码:
<!doctype html>
<html lang="zh_cn">
<head>
<title>HTML5 localStorage 便利贴</title>
<meta charset="UTF-8" />
<meta name="author" content="晓风东东" />
<meta name="keywords" content="HTML5,locaStorage,HSL,便利贴,即时贴" />
<meta name="description" content="一个基于HTML5和CSS3技术的便利贴应用,你可以写入一些待办事项。这些东西会完整的保存在你的浏览器里,除非你清空缓存。" />
<link rel="stylesheet" href="css/style.css">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/js.js"></script>
</head>
<body>
<section id="shell">
<form id="ctrl_form">
<div id="title">HTML5 localStorage 便利贴</div>
<label for="note_color">颜色:</label>
<select id="note_color">
<option>随机</option>
<option>科技蓝</option>
<option>淡雅黄</option>
<option>清新绿</option>
<option>暧昧粉</option>
<option>高贵紫</option>
</select>
<input type="text" id="note_text" />
<input type="button" id="add_btn" value="增加" />
</form>
<section id="note_display">
<ul id="note_display_ul">
</ul>
</section><!--note_display end-->
</section><!--shell end-->
</body>
</html>
CSS源码:
html,body {
background:url(../images/bg.png);
font-family:"微软雅黑";
}
#ctrl_form {
background:-webkit-gradient(linear, 0 0, 0 100%, from(#2c2f36), to(#16181c));
width:60%;
border-radius:5px;
margin:0 auto;
margin-top:5%;
text-align:center;
padding:1%;
color:#fff;
}
#title {
font-size:200%;
padding-bottom:10px;
margin-bottom:10px;
border-bottom:2px dashed #888;
text-shadow:2px 1px 2px #888;
}
#note_display {
width:90%;
margin:0 auto;
text-align:center;
margin-top:5%;
}
#note_display ul li {
width:10%;
background:hsl(110,53%,60%);
background-image:url(../images/wangge.png);
height:150px;
float:left;
border:1px solid #aeaeae;
color:#222;
font-size:150%;
padding:1%;
margin:1%;
cursor:pointer;
overflow:hidden;
box-shadow: 2px 2px 8px #222;
}
#note_display ul li:hover {
opacity:.8;
}
#add_btn,#note_text,#note_color,label {
font-family:"微软雅黑";
font-size:150%;
padding:.5%;
}
#note_color {
padding:.4%;
}
#add_btn {
background:-webkit-gradient(linear, 0 0, 0 100%, from(#aeaeae), to(#888));
border:1px solid #aeaeae;
color:#000;
}
#add_btn:hover {
background:-webkit-gradient(linear, 0 0, 0 100%, from(#888), to(#aeaeae));
}
#note_text {
width:30%;
}
/*响应式web设计的核心,为不同设备屏幕写出独立的CSS,同时尽量避免使用PX作为宽度的单位,更多的使用相对单位。*/
@media screen and (max-width:720px) {
#note_display ul li {
width:20%;
}
}
@media screen and (max-width:480px) {
#note_display ul li {
width:40%;
font-size:120%;
}
}
终于要到了最头疼的JS源码了,不过也是最有技术含量的部分:
$(document).ready(function(){
//给增加按钮绑定事件,并设置在点击增加后输入框内清空
$("#add_btn").click(function(){
var note_text_val = $("#note_text").val();
if (note_text_val == ""){
alert("亲,你还没有填写任何内容喔!");
}
else {
createSticky();
$("#note_text").val("");
}
});
//遍历便利贴数组,同时传递值给其他函数
//JSON.parse是个非常神奇的函数,可以给你把数组或者对象的内容转化为字符串。就像JSON那样,很棒!这使的我可以在Cookies或者localStore中存储更多的数据
var stickiesArray = getStickiesArray();
for(var i= 0 ; i < stickiesArray.length; i++){
var key = stickiesArray[i];
var value = JSON.parse(localStorage[key]);
addStickyToDOM(key, value);
}
});
//创建stickiesArray,存放一个类似电话本的键,并且对localStorage中的stickiesArray这个“母键”初始化
function getStickiesArray() {
var stickiesArray = localStorage["stickiesArray"];
if(!stickiesArray) {
stickiesArray = [];
localStorage.setItem("stickiesArray", JSON.stringify(stickiesArray));
}
else {
stickiesArray = JSON.parse(stickiesArray);
}
return stickiesArray;
}
//创建其他键值,并且从用户界面得到所选颜色值,并且转换为HSL值,写入localStorage
//stickyObj是一个对象,不同于数组了。对象是个很抽象的玩意,Everything is an object
function createSticky (){
var stickiesArray = getStickiesArray();
var currentDate = new Date();//按照时间获得一个随机数,保证键值不重复
var colorSelectObj = document.getElementById("note_color");
var index = colorSelectObj.selectedIndex;
var colorName = colorSelectObj[index].value;
var colorHSL = colorNameToHSL(colorName);
var value = $("#note_text").val();
var key = "sticky_" + currentDate.getTime();
var stickyObj = {
"value": value,
"colorHSL": colorHSL
}
//将对象写入localStorage
localStorage.setItem(key, JSON.stringify(stickyObj));
//将键名添加到哪个神奇的母键的最后一项
stickiesArray.push(key);
localStorage.setItem("stickiesArray", JSON.stringify(stickiesArray));
//添加便贴到DOM
addStickyToDOM(key, stickyObj);
}
//添加便贴到DOM的具体步骤,stickyObj是一个对象,要用.来访问子元素
function addStickyToDOM (key, stickyObj){
var sticky = document.createElement("li");
sticky.setAttribute("id", key);
sticky.setAttribute("style", "background-color:hsl(" + stickyObj.colorHSL +", 56%, 60%);");//HSL中的色相保持随机,其他的固定上。保证颜色的饱和度和亮度
var span = document.createElement("span");
span.setAttribute("class", "sticky");
span.innerHTML = stickyObj.value;
sticky.appendChild(span);
$("#note_display_ul").append(sticky);
sticky.onclick = deleteSticky;
}
//删除即时贴的函数,做了一个判断,判断点击对象并确保为ul下的li元素,而不是span
//同时还要更新删除过后的stickiesArray数组
function deleteSticky (e){
if(confirm("你确定要删除这个即时贴吗?")){
var key = e.target.id;
if(e.target.tagName.toLowerCase() == "span") {
key = e.target.parentNode.id;
}
localStorage.removeItem(key);
var stickiesArray = getStickiesArray();
if(stickiesArray) {
for (var i = 0; i< stickiesArray.length; i++) {
if(key == stickiesArray[i]){
stickiesArray.splice(i,1);
}
}
localStorage.setItem("stickiesArray", JSON.stringify(stickiesArray));
removeStickyFromDom(key);
}
}
}
//从DOM中删除已经删除的便贴
function removeStickyFromDom(key) {
var sticky = document.getElementById(key);
sticky.parentNode.removeChild(sticky);
}
//将colorName根据HSL的颜色值进行分析并返回
function colorNameToHSL(colorName) {
if(colorName == "科技蓝") {
return 200;
}
else if (colorName == "淡雅黄"){
return 60;
}
else if (colorName == "清新绿"){
return 100;
}
else if (colorName == "暧昧粉"){
return 325;
}
else if (colorName == "高贵紫"){
return 250;
}
else{
var random_num = Math.floor(Math.random()*359+1);
return random_num;
}
}