在本文中,我们将使用 HTML、CSS 和 JavaScript 创建一个站点书签应用程序。这将有助于我们在不使用任何数据库的情况下存储指向我们最喜欢的网站的链接,而只需使用浏览器的本地存储。
本地存储被称为 Web 存储 API,它允许我们在客户端存储数据。本地存储中的数据以字符串的形式存储,即使在关闭会话后仍然存在。只有用户手动删除数据才能删除数据。所有数据都保留在客户端,因此对值的长度有明确的限制,根据我们使用的浏览器,我们目前可以存储2 MB 到 10 MB大小的数据。
方法:我们正在设计的书签应用程序可以执行以下操作:
- 添加一个带有用户键入的名称和网站链接的新书签。
- 包含访问网站的选项
- 删除书签
- 然后始终将书签永久保存在 LocalStorage 上
项目概况:
文件结构:
- 索引.html
- 样式文件
- 主文件
我们将使用 HTML 来设计网页结构或布局。这包括:
- 标题部分:这包括我们网页的标题。这里的标题是“站点书签”。
- 容器部分:它包含表单和书签部分。
- 表单部分:它包括两个输入字段,用于站点名称和链接。它还包含一个用于提交表单的“保存”按钮。
- 书签部分:此部分将包含我们保存的所有书签,并将根据输入动态更改。
HTML
Site Bookmarker
Site Bookmarker
Saved Bookmarks
CSS
*{
box-sizing: border-box;
font-family: sans-serif;
}
body{
margin: 0;
padding: 0;
background-color: #333333;
}
a{
text-decoration: none;
color: #fff;
}
/*Styling title*/
h1{
width: 100%;
height: 80px;
text-align: center;
line-height: 80px;
margin: 0;
padding: 0;
background-color: #47CF73;
letter-spacing: 2px;
word-spacing: 8px;
color: #000;
}
h2{
color: #47CF73;
}
.container{
width: 600px;
min-height: 150px;
background-color: #333333;
margin: 0 auto;
}
/*Styling form section*/
.form{
width: 100%;
height: auto;
background-color: #555555;
padding: 40px 50px;
margin: 20px 0;
}
.input-field{
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 15px;
}
.input-field input[type="text"]{
width: 250px;
height: 25px;
outline: none;
border: none;
background-color: transparent;
border-bottom: 2px solid #47CF73;
padding-left: 10px;
color: #fff;
}
.input-field label{
color: #47CF73;
font-weight: bold;
margin-bottom: 5px;
}
.save_button{
display: block;
margin: 0 auto;
border: none;
width: 70px;
height: 25px;
background-color: #47CF73;
color: #000;
cursor: pointer;
outline: none;
}
/*Styling Bookmarks section*/
.bookmarks{
width: 100%;
background-color: #555555;
padding: 20px;
}
.bookmark{
display: flex;
align-items: center;
width: 300px;
height: 40px;
padding: 5px 20px;
background-color: #FAFAFA;
margin-bottom: 10px;
background-color: #333333;
}
.bookmark span{
flex: 1;
font-weight: bold;
letter-spacing: 1.5px;
color: #fff;
}
.bookmark .visit{
width: 50px;
height: 25px;
line-height: 25px;
text-align: center;
background-color: #47CF73;
color: #000;
border-radius: 5px;
margin: 0 5px;
}
.bookmark .delete{
width: 60px;
height: 25px;
line-height: 25px;
text-align: center;
background-color: #F44336;
border-radius: 5px;
}
Javascript
// Select the save button
var button = document.querySelector(".save_button");
// Select the input box
var siteName = document.querySelector("[name='site_name']");
var url = document.querySelector("[name='url']");
// Select the with class="bookmarks"
var bookmarksSection = document.querySelector(".bookmarks");
// Hold bookmarks in local storage
if(typeof(localStorage.bookmark) == "undefined"){
localStorage.bookmark = "";
}
Javascript
// listen for form submit
button.addEventListener("click", function(e){
// Prevent the page from reloading when submitting the form
e.preventDefault();
let patterURL = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
let arrayItems, check = false, adr, itemAdr;
// Validation of form and URL
if(siteName.value === ""){
alert("you must fill the siteName input");
} else if(url.value === ""){
alert("you must fill the url input");
} else if(!patterURL.test(url.value)){
alert("you must enter a valid url");
} else{
arrayItems = localStorage.bookmark.split(";");
adr = url.value;
adr = adr.replace(/http:\/\/|https:\/\//i, "");
arrayItems.length--;
// Check if website is already bookmarked
for(item of arrayItems){
itemAdr = item.split(',')[1].replace(/http:\/\/|https:\/\//i,"");
if(itemAdr == adr){
check = true;
}
}
if(check == true){
alert("This website is already bookmarked");
}
else{
// If all checks are correct,add bookmark to local storage
localStorage.bookmark += `${siteName.value},${url.value};`;
addBookmark(siteName.value, url.value);
siteName.value = "";
url.value = "";
}
}
});
Javascript
// Function to add the bookmark
function addBookmark(name, url){
let dataLink = url;
// After obtaining a bookmark, we display it in a div and add
// a button to visit the link or to delete it
if(!url.includes("http")){
url = "//" + url;
}
let item = ``;
bookmarksSection.innerHTML += item;
}
Javascript
// function to render the saved bookmarks
(function fetchBoookmark(){
if(typeof(localStorage.bookmark) != "undefined" && localStorage.bookmark !== ""){
let arrayItems = localStorage.bookmark.split(";");
arrayItems.length--;
for(item of arrayItems){
let itemSpli = item.split(',');
addBookmark(itemSpli[0], itemSpli[1]);
}
}
})();
Javascript
// Function to remove the bookmark
function removeBookmark(thisItem){
let arrayItems = [],
index,
item = thisItem.parentNode,
itemURL = item.querySelector(".visit").dataset.link,
itemName = item.querySelector("span").innerHTML;
arrayItems = localStorage.bookmark.split(";");
for(i in arrayItems){
if(arrayItems[i] == `${itemName},${itemURL}`){
index = i;
break;
}
}
//update the localStorage
index = arrayItems.indexOf(`${itemName},${itemURL}`);
arrayItems.splice(index,1);
localStorage.bookmark = arrayItems.join(";");
//update the bookmark Section
bookmarksSection.removeChild(item);
}
CSS 样式: CSS 用于设置不同部分的样式并使它们更具视觉吸引力。
- 表单和书签部分使用 flex 布局显示。
- 为每个元素提供了足够的填充和边距。
- 每个元素的文本大小、颜色以及背景颜色都易于用户阅读。
- 需要时会动态添加或删除单个书签。
CSS
*{
box-sizing: border-box;
font-family: sans-serif;
}
body{
margin: 0;
padding: 0;
background-color: #333333;
}
a{
text-decoration: none;
color: #fff;
}
/*Styling title*/
h1{
width: 100%;
height: 80px;
text-align: center;
line-height: 80px;
margin: 0;
padding: 0;
background-color: #47CF73;
letter-spacing: 2px;
word-spacing: 8px;
color: #000;
}
h2{
color: #47CF73;
}
.container{
width: 600px;
min-height: 150px;
background-color: #333333;
margin: 0 auto;
}
/*Styling form section*/
.form{
width: 100%;
height: auto;
background-color: #555555;
padding: 40px 50px;
margin: 20px 0;
}
.input-field{
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 15px;
}
.input-field input[type="text"]{
width: 250px;
height: 25px;
outline: none;
border: none;
background-color: transparent;
border-bottom: 2px solid #47CF73;
padding-left: 10px;
color: #fff;
}
.input-field label{
color: #47CF73;
font-weight: bold;
margin-bottom: 5px;
}
.save_button{
display: block;
margin: 0 auto;
border: none;
width: 70px;
height: 25px;
background-color: #47CF73;
color: #000;
cursor: pointer;
outline: none;
}
/*Styling Bookmarks section*/
.bookmarks{
width: 100%;
background-color: #555555;
padding: 20px;
}
.bookmark{
display: flex;
align-items: center;
width: 300px;
height: 40px;
padding: 5px 20px;
background-color: #FAFAFA;
margin-bottom: 10px;
background-color: #333333;
}
.bookmark span{
flex: 1;
font-weight: bold;
letter-spacing: 1.5px;
color: #fff;
}
.bookmark .visit{
width: 50px;
height: 25px;
line-height: 25px;
text-align: center;
background-color: #47CF73;
color: #000;
border-radius: 5px;
margin: 0 5px;
}
.bookmark .delete{
width: 60px;
height: 25px;
line-height: 25px;
text-align: center;
background-color: #F44336;
border-radius: 5px;
}
逻辑:我们应用的主要逻辑是使用 JavaScript 实现的。有几个功能可以为应用程序协同工作。
步骤 1(选择所有元素并定义变量):
- 我们需要做的第一件事是从 DOM 中获取我们需要的所有内容的引用。使用 querySelector() 方法选择 HTML 布局中所需的元素。
- 这将从 DOM 中获取“.bookmarks”、“.save_button”以及诸如“site_name”和“url”之类的输入字段,并将它们存储在相应的变量中。
- 它们被分配了变量名,以便可以轻松访问和修改它们。
- 此外,为我们的本地存储定义书签对象以保存所有书签。
Javascript
// Select the save button
var button = document.querySelector(".save_button");
// Select the input box
var siteName = document.querySelector("[name='site_name']");
var url = document.querySelector("[name='url']");
// Select the with class="bookmarks"
var bookmarksSection = document.querySelector(".bookmarks");
// Hold bookmarks in local storage
if(typeof(localStorage.bookmark) == "undefined"){
localStorage.bookmark = "";
}
Step2(获取表单中提交事件的值和设置验证):
- 我们有用于保存按钮的 EventListener 来监听表单上的点击事件。每当点击事件发生时,该函数就会激活。
- 每次提交表单时,页面都会重新加载。所以为了阻止我们调用 e.preventDefault()。
- 我们可以分别从 siteName.value 和 url.value 中获取用户键入的名称和 url。
- 包括一些验证以确保我们不会保存两次并且我们的表单不为空。
- 在所有验证之后,将用户键入的值传递给 addBookmark()函数。
注意:我们可以使用 setItem() 方法将项目存储在 localStorage 上,该方法需要一个键和一个值。在这里,我们使用“localStorage.bookmark”,它会自动创建一个书签作为我们 localStorage 中的键。
Javascript
// listen for form submit
button.addEventListener("click", function(e){
// Prevent the page from reloading when submitting the form
e.preventDefault();
let patterURL = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
let arrayItems, check = false, adr, itemAdr;
// Validation of form and URL
if(siteName.value === ""){
alert("you must fill the siteName input");
} else if(url.value === ""){
alert("you must fill the url input");
} else if(!patterURL.test(url.value)){
alert("you must enter a valid url");
} else{
arrayItems = localStorage.bookmark.split(";");
adr = url.value;
adr = adr.replace(/http:\/\/|https:\/\//i, "");
arrayItems.length--;
// Check if website is already bookmarked
for(item of arrayItems){
itemAdr = item.split(',')[1].replace(/http:\/\/|https:\/\//i,"");
if(itemAdr == adr){
check = true;
}
}
if(check == true){
alert("This website is already bookmarked");
}
else{
// If all checks are correct,add bookmark to local storage
localStorage.bookmark += `${siteName.value},${url.value};`;
addBookmark(siteName.value, url.value);
siteName.value = "";
url.value = "";
}
}
});
第 3 步(向我们的网页添加书签):这个 addBookmark()函数将以站点名称和 url 作为其参数。然后:
- 构造一个新的书签对象。
- 该对象具有名称、URL 以及访问和删除属性。
- 然后它将该对象推送到 HTML 页面的书签部分。
- 在此之后,我们将调用 fetchBookmark()函数。该函数负责将每个项目渲染到屏幕上。
Javascript
// Function to add the bookmark
function addBookmark(name, url){
let dataLink = url;
// After obtaining a bookmark, we display it in a div and add
// a button to visit the link or to delete it
if(!url.includes("http")){
url = "//" + url;
}
let item = ``;
bookmarksSection.innerHTML += item;
}
第 4 步(渲染保存的书签):现在我们可以将书签添加到我们的应用程序并将它们存储在 localStorage 中。但是当我们刷新页面或开始新会话时,即使存储在 localStorage 中,所有书签也会从网页中消失。
所以我们需要通过使用 fetchBookmark()函数从 localStorage 获取书签来持久化它们。
- 首先,我们将检查定义的书签键是否为空。如果它不为空,则:
- 我们将使用 split() 方法创建一个包含所有书签的数组。
- 接下来,将循环遍历里面的每个项目。对于每个书签,我们将获得名称和网址。
- 为了显示这些项目,我们将调用 addBookmark()函数。
Javascript
// function to render the saved bookmarks
(function fetchBoookmark(){
if(typeof(localStorage.bookmark) != "undefined" && localStorage.bookmark !== ""){
let arrayItems = localStorage.bookmark.split(";");
arrayItems.length--;
for(item of arrayItems){
let itemSpli = item.split(',');
addBookmark(itemSpli[0], itemSpli[1]);
}
}
})();
第 5 步(删除书签):访问链接很简单,我们只需跟踪 URL,但要删除它,我们需要在 localStorage 中识别特定 URL,然后将其从我们的对象中删除。
为此,我们将编写一个 removeBookmark()函数。
- 首先,我们将从 localStorage 中获取所有书签并将它们存储在一个数组中。
- splice() 方法用于从数组中删除项目并返回更新的项目。
- 此外,我们将使用 removeChild() 方法从书签的父节点中删除子节点。
Javascript
// Function to remove the bookmark
function removeBookmark(thisItem){
let arrayItems = [],
index,
item = thisItem.parentNode,
itemURL = item.querySelector(".visit").dataset.link,
itemName = item.querySelector("span").innerHTML;
arrayItems = localStorage.bookmark.split(";");
for(i in arrayItems){
if(arrayItems[i] == `${itemName},${itemURL}`){
index = i;
break;
}
}
//update the localStorage
index = arrayItems.indexOf(`${itemName},${itemURL}`);
arrayItems.splice(index,1);
localStorage.bookmark = arrayItems.join(";");
//update the bookmark Section
bookmarksSection.removeChild(item);
}
输出:您已经完成了,我们的站点书签应用程序已准备就绪。也可以在localStorage中看到存储的书签,如下图:
此站点书签应用程序包含使用本地存储添加、存储和删除的基本功能。您可以发挥创意并添加编辑函数,或使用嵌套列表创建集合来存储书签。
如果您想了解有关本地存储及其功能的更多信息,可以访问以下站点:本地和会话存储