这是来自Learning JavaScript By Building A Boookmarker Application的笔记。
首先做出来的效果是这样的:
输入网站名和网站地址,点击提交,即可显示在下方:
点击访问,跳转到该网站;点击删除则去掉该条目。
数据存储在localStorage
中,核心就是:
localStorage.getItem('xxx'); // 获取
localStorage.setItem('xxx',字符串型数值);
定义的JS对象存储到localStorage
时需要JSON.stringify(js_object)
,取出来对象需要用:JSON.parse()
。
存储模式是键值对存储。
完整的前端代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Site Bookmarker</title>
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
</head>
<!-- onload="fetchBookmarks()" -->
<body onload="fetchBookmarks()">
<div class="container">
<div class="header clearfix">
<nav>
</nav>
<h3 class="text-muted">Bookmarker</h3>
</div>
<div class="jumbotron">
<h2>Bookmark Your Favorite Sites</h2>
<form id="myForm">
<div class="form-group">
<label>Site Name</label>
<input type="text" class="form-control" id="siteName" placeholder="Website Name">
</div>
<div class="form-group">
<label>Site URL</label>
<input type="text" class="form-control" id="siteUrl" placeholder="Website URL">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<!-- 用于显示书签数据 -->
<div class="row marketing">
<div class="col-lg-12">
<div id="bookmarksResults"></div>
</div>
</div>
<footer class="footer">
<p>© 2018 Bookmarker, Inc.</p>
</footer>
</div> <!-- /container -->
<script
src="https://code.jquery.com/jquery-3.1.1.js"
integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
crossorigin="anonymous"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
前端逻辑代码:
// 为表单添加监听事件
document.getElementById('myForm').addEventListener('submit', saveBookmark);
function saveBookmark(e) {
var siteName = document.getElementById('siteName').value;
var siteUrl = document.getElementById('siteUrl').value;
var bookmark = {
name: siteName,
url: siteUrl
};
// console.log(bookmark);
/*
// 本地存储
localStorage.setItem('test', 'hello world'); // 添加键值数据
console.log(localStorage.getItem('test')); // 获取数据
localStorage.removeItem('test'); // 移除数据
console.log(localStorage.getItem('test'));
*/
// 测试看看是否已经有这个数据
if(localStorage.getItem('bookmarks') == null) {
var bookmarks = [];
// 添加到数组
bookmarks.push(bookmark);
// 设置到localStorage
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
} else {
// 从本地存储拿出数据
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
bookmarks.push(bookmark);
// 再存入到localStorage
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}
// 页面重新加载
window.location.reload();
// 禁止默认的闪现行为
e.preventDefault();
}
function deleteBookmark(url) {
// console.log(url);
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
for(var i = 0; i < bookmarks.length; i++) {
if(bookmarks[i].url == url) {
// 从数组中移除
bookmarks.splice(i,1);
}
}
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
// re-fetch
fetchBookmarks();
}
// Fetch bookmarks
function fetchBookmarks() {
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
// console.log(bookmarks);
var bookmarksResults = document.getElementById('bookmarksResults');
bookmarksResults.innerHTML = "";
for(var i = 0;i < bookmarks.length; i++) {
var name = bookmarks[i].name;
var url = bookmarks[i].url;
// 直接加的是HTML标记,前端自动显示
bookmarksResults.innerHTML += '<div class="well">' +
'<h3>' + name +
' <a class="btn btn-default" target="_blank" href="https://' + url + '">Visit</a> ' +
' <a onclick="deleteBookmark(\''+url+'\')" class="btn btn-danger" target="_blank" href="#">Delete</a> ' +
'</h3>' +
'</div>';
}
}
这是用最原生的方式完成了上面的需求。
开发过程
首先,界面显示是用Bootstrap
来保证显示效果,定义好一个显示界面,这个界面上最核心的部分是两个:
- 表格:label + input + button
- 展示已有书签列表
显然,在点击Submit
按钮后,我们需要提取出来两个输入框的数据,保存到localStorage
,也就是说,Submit
按钮需要添加一个监听函数:
document.getElementById('myForm').addEventListener('submit', saveBookmark);
这个监听函数的写法也很简单,提取输入数值,保存起来。
function saveBookmark() {
var siteName = document.getElementById('siteName').value;
var siteUrl = document.getElementById('siteUrl').value;
var bookmark = {
name: siteName,
url: siteUrl
};
// 测试看看是否已经有这个数据
if(localStorage.getItem('bookmarks') == null) {
var bookmarks = [];
// 添加到数组
bookmarks.push(bookmark);
// 设置到localStorage
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
} else {
// 从本地存储拿出数据
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
bookmarks.push(bookmark);
// 再存入到localStorage
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}
// 页面重新加载--刷新
window.location.reload();
// 禁止默认的闪现行为
e.preventDefault();
}
解释一下这里为什么现在内存中设定一个数组对象的原因,存储在localStorage
里的值是字符串类型,我们得将对象序列化为字符串,才能保存,所以先保存到bookmarks
对象,然后将新值push
到该对象,序列化后存储到localStorage
。
localStorage
对象在JS中直接可用。
新添加的Visit
和Delete
,看起来都是Button
,是因为用了CSS
样式,用的都是a
标签。
页面一进来,就需要拿到显示数据,定义一个函数fetchBookmarks
,在body
部分<body onload="fetchBookmarks()">
。
// Fetch bookmarks
function fetchBookmarks() {
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
// console.log(bookmarks);
var bookmarksResults = document.getElementById('bookmarksResults');
bookmarksResults.innerHTML = "";
for(var i = 0;i < bookmarks.length; i++) {
var name = bookmarks[i].name;
var url = bookmarks[i].url;
// 直接加的是HTML标记,前端自动显示
bookmarksResults.innerHTML += '<div class="well">' +
'<h3>' + name +
' <a class="btn btn-default" target="_blank" href="https://' + url + '">Visit</a> ' +
' <a onclick="deleteBookmark(\''+url+'\')" class="btn btn-danger" target="_blank" href="#">Delete</a> ' +
'</h3>' +
'</div>';
}
}
然后为删除书签添加一个响应函数:
function deleteBookmark(url) {
// console.log(url);
var bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
for(var i = 0; i < bookmarks.length; i++) {
if(bookmarks[i].url == url) {
// 从数组中移除
bookmarks.splice(i,1);
}
}
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
// re-fetch
fetchBookmarks();
}
也是先从localStorage
中取出来存到数组对象,遍历数组删除该数据,再存回到localStorage
。
主要逻辑就这些,完整代码文章开头就放了。
END.