快递案例(localStorage缓存版)
- 案例名称:快递案例webSql版
- 案例人员:杨标
- 案例平台:HTML+CSS+JavasScript+jQuery+template+iconfont+Ajax
- 完成时间:2019年9月12日
::: tip 提示
本案例可下载
:::
效果图
案例说明
本案例旨在对jQuery里面的ajax做一次基础的练习,同时能够了 解get请求的原理,了解URL地址中的请求地址与请求参数的区别
本案例分为两个页面,一个是查询快递的页面,一个是快递查询的历史记录的页面,在历史记录的页面要实现左滑删除,同时点击历史记录以后要跳到查询的页面进行查询
在页面进行跳转的时候,要使用地HTML静态页面的跨页面传值技术,本案例使用的是URLSearchParams
这个对象,它是HTML5里面新出的对象,也是现在常用的一种跨页面传值技术
本案例当中的历史记录有两个版本,一个是通过localStorage
的方式进行的存储,一个是通过webSql
的方式在进行存储
案例代码
本案例分为两个页面,目录结构如下所示
主页功能
index.html页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>快递查询</title>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 750 * 100 + "px";
})
</script>
<link rel="stylesheet" href="./css/index.css" type="text/css">
<link rel="stylesheet" href="http://at.alicdn.com/t/font_1307637_s4x727lwhxf.css">
<!-- 导入layer插件的css -->
<link rel="stylesheet" href="./js/layer/theme/default/layer.css">
</head>
<body>
<div id="app">
<!--头部的标题-->
<div class="header">快递查询</div>
<!-- 中间的主体 -->
<div class="content">
<div class="formBox">
<select id="kdType">
<option value="">-请选择快递类型-</option>
</select>
<input type="text" id="postId" placeholder="请输入快递单号">
<button type="button" class="btnQuery">查询</button>
</div>
<!--在这里应该有个结果-->
<ul class="resultList"></ul>
</div>
<!-- 下边的tabBar -->
<ul class="tabBar">
<li style="color: deeppink">
<span class="iconfont icon-chaxun"></span>
<span>查询</span>
</li>
<li onclick="location.href='history.html'">
<span class="iconfont icon-wode"></span>
<span>我的</span>
</li>
</ul>
</div>
<template id="kdTypeTemp">
{{each kdComList item index}}
<option value="{{item.key}}">{{item.com}}</option>
{{/each}}
</template>
<template id="resultListTemp">
{{each traces item index}}
<li>
<div class="time">{{item.AcceptTime}}</div>
<div class="state">{{item.AcceptStation}}</div>
</li>
{{/each}}
</template>
</body>
<script src="./js/jquery.js" type="text/javascript"></script>
<script src="./js/template-web.js" type="text/javascript"></script>
<script src="./js/juqery.extend.js" type="text/javascript"></script>
<script src="./js/layer/layer.js" type="text/javascript"></script>
<script>
//页面加载的时候,请求快递数据,获取快递公司
var kdComList = []; //定义了一个数组,用于存放所有快递公司的信息
var kdHistory = null; //定义一个数组,用于存放历史记录
$(function () {
if (localStorage.getItem("kdComList")) {
kdComList = JSON.parse(localStorage.getItem("kdComList"));
$("#kdType").renderTpl("kdTypeTemp", {
kdComList: kdComList
});
} else {
//同学们做的时候,请把快递公司做个缓存
layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
}); //出现加载动画
//如果我需要向服务器发送数据,那么我就把数据把在方法里面的第二个参数里在
$.get("https://www.softeem.xin/Api/KuaiDi/getKuaiDiCom", function (data) {
//data代表的是服务器返回给我们的数据,它不是固定的,服务器返回的是什么,我们得到的就是什么!
$("#kdType").renderTpl("kdTypeTemp", {
kdComList: data
});
kdComList = data;
layer.closeAll();
localStorage.setItem("kdComList", JSON.stringify(kdComList));
});
}
//查询事件
$(".btnQuery").click(function () {
var type = $("#kdType").val(); //快递类型 ,它是一个key
var postId = $("#postId").val(); //快递单号,它是一个字符串
//如果用户没有输入快递单号,则提示框
if (postId == "") {
//说明没有输入
layer.alert("请输入快递单号")
} else {
queryKuaiDi(type, postId);
}
});
(function () {
//我要在这里检测一下,当前这个页面有没有参数给我
//如果有参数给我,就说明是从历史记录的页面跳过来(获取参数,查询快递),如果没有参数,就是直接打开的
var searchParams = new URLSearchParams(location.search);
var postId = searchParams.get("postId");
var type = searchParams.get("type");
if (postId && type) {
queryKuaiDi(type, postId);
}
})();
//查询快递的方法
function queryKuaiDi(type, postId) {
//出现加载动画
layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
//应该是将快递类型与快递单号发送给服务器
var url = "https://www.softeem.xin/Api/KuaiDi/getKuaiDiInfo?type=" + type + "&postId=" +
postId;
$.get(url, function (data) {
layer.closeAll();
$(".resultList").renderTpl("resultListTemp", {
traces: data.Traces
});
//保存历史记录 先讲storage版本
//1.先看一下有没有缓存kdHistory
if (localStorage.getItem("kdHistory")) {
//说明原来有
kdHistory = JSON.parse(localStorage.getItem("kdHistory"));
} else {
//说明没有
kdHistory = [];
}
//2.去历史记录里面去找,之前我有没有查询过一条这样的快递
var arr = kdHistory.filter(function (item, index, a) {
return item.postId == postId
});
if (arr.length > 0) {
//存在 把这条记录找出来
var currentObj = arr[0]; //这是对象 这是浅拷贝 currentObj改变,arr[0]也改
currentObj.time = new Date().toLocaleString(); //把时间换成当前时间
currentObj.lastInfo = data.Traces[data.Traces.length - 1].AcceptTime + " " + data
.Traces[data.Traces.length - 1].AcceptStation
//再放到缓存里面去
localStorage.setItem("kdHistory", JSON.stringify(kdHistory));
} else {
//不存在
//我们假设没有
//是否可以拿快递公司的名称
var com = kdComList.filter(function (item, index, a) {
return item.key == type;
})[0].com;
kdHistory.push({
time: new Date().toLocaleString(),
postId: postId,
lastInfo: data.Traces[data.Traces.length - 1].AcceptTime +
" " +
data.Traces[data.Traces.length - 1].AcceptStation,
type: type, //快递公司的编号
com: com //快递公司的名称
})
//再放到缓存里面去
localStorage.setItem("kdHistory", JSON.stringify(kdHistory));
}
});
}
})
/*
1.jQuery
2.移动端布局
3.Ajax
4.请求地址与请求参数
5.学会了看API文档
6.缓存的练习
7.跨页面的传值 URLSearchParams
8.模板引擎的使用
9.事件委托 的应用场景
10.layer.js的初步使用
11.jQuery扩展方法的应用
12.iconfont的使用
13.触摸实现在滑删除
14.CSS移动端取消高亮,以及下拉框去掉箭头
15.jQuery的event找到原始事件
16.JSON的转换 JSON.parse与JSON.stringify
*/
</script>
</html>
index.css的代码
@charset "utf-8";
*{
margin: 0px;
padding: 0px;
list-style-type: none;
/* 取消按钮与a标签点击的时候的高亮效果 */
-webkit-tap-highlight-color: transparent;
}
body{
font-size: 16px;
}
#app{
width:100vw;
height:100vh;
display:flex;
flex-direction: column;
}
.header{
height: .9rem;
background-color: deeppink;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-weight: bold;
font-size: .44rem;
}
.content{
flex: 1;
overflow: auto;
background-image: radial-gradient(deeppink,white);
}
.tabBar{
width:100%;
display: flex;
height: 1.1rem;
border-top: 1px solid #ececec;
justify-content: space-around;
}
.tabBar li{
height: inherit;
width: 1.1rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.tabBar li span.iconfont{
font-size: .44rem;
}
.tabBar li span:last-child{
font-size: .24rem;
}
.formBox{
box-sizing: border-box;
padding: .4rem;
}
#kdType,#postId{
width: 100%;
padding: 10px;
margin-top: .2rem;
box-sizing: border-box;
border:none;
/* 去掉下拉框的小箭头 */
-webkit-appearance: none;
}
.btnQuery{
width: 100%;
border: none;
padding: 10px;
background-color: white;
margin-top: .2rem;
cursor: pointer;
box-shadow: 2px 4px 2px red;
outline: none;
}
.btnQuery:active{
transform: translate(2px,4px);
box-shadow: none;
}
.resultList{
padding: .2rem;
font-size: .24rem;
}
.resultList li{
display: flex;
border-radius:2px;
background-color:rgba(255,255,255,0.3);
}
.resultList li .time{
width: 2.2rem;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
position:relative;
padding:0.1rem;
}
.resultList li .time::after{
content:"";
display:block;
position:absolute;
height:100%;
border-right:1px solid #ececec;
right:0px;
}
.resultList li .state{
flex: 1;
display:flex;
align-items:center;
padding:0.1rem;
padding-left:0.25rem;
position:relative;
}
.resultList li .state::before{
content:"";
display:block;
position:absolute;
width:10px;
height:10px;
border-radius:50%;
background-color:lightgray;
left:-5px;
}
.resultList li:first-child .time::after{
height:50%;
top:50%;
}
.resultList li:last-child .time::after{
height:50%;
top:0px
}
.resultList li:first-child .state::before{
background-color:deeppink;
}
.resultList li:first-child{
color:deeppink;
}
上面的HTML代码与CSS代码已经可以完成主页的效果了,现在我们再进行历史记录页面的完成功能
历史记录页功能
该页面主要的功能就是将之前的查询记录缓存起来,方便用户以后再次去查询
history.html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>快递查询</title>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 750 * 100 + "px";
})
</script>
<link rel="stylesheet" href="./css/index.css" type="text/css">
<link rel="stylesheet" href="http://at.alicdn.com/t/font_1307637_s4x727lwhxf.css">
<!-- 导入layer插件的css -->
<link rel="stylesheet" href="./js/layer/theme/default/layer.css">
<link rel="stylesheet" href="./css/history.css">
</head>
<body>
<div id="app">
<!--头部的标题-->
<div class="header">历史记录</div>
<!-- 中间的主体 -->
<div class="content">
<ul class="historyList">
</ul>
</div>
<!-- 下边的tabBar -->
<ul class="tabBar">
<li onclick="location.href='index.html'">
<span class="iconfont icon-chaxun"></span>
<span>查询</span>
</li>
<li style="color:deeppink">
<span class="iconfont icon-wode"></span>
<span>我的</span>
</li>
</ul>
</div>
<template id="historyItemTemp">
{{each kdHistory item index}}
<li>
<div class="historyItem" data-type="{{item.type}}" data-postid="{{item.postId}}">
<div class="top">
<div>
<span>{{item.com}}</span>
<span>{{item.postId}}</span>
</div>
<div>{{item.time}}</div>
</div>
<div class="bottom">{{item.lastInfo}}</div>
</div>
<div class="delBtn">删除</div>
</li>
{{/each}}
</template>
</body>
<script src="./js/jquery.js" type="text/javascript"></script>
<script src="./js/template-web.js" type="text/javascript"></script>
<script src="./js/juqery.extend.js" type="text/javascript"></script>
<script src="./js/layer/layer.js" type="text/javascript"></script>
<script>
$(function () {
//当页面加载完毕以后,我要去判断缓存时面有没有历史记录
var kdHistory = [];
if (localStorage.getItem("kdHistory")) {
kdHistory = JSON.parse(localStorage.getItem("kdHistory"));
}
//在通过模板引擎去调用
$(".historyList").renderTpl("historyItemTemp", {
kdHistory: kdHistory
});
//点击历史记录重新查询
$(".historyList").on("click", ".historyItem", function () {
//我们要取到快递类型与快递的单号
var type = $(this).data("type");
var postId = $(this).data("postid");
location.href = "index.html?type=" + type + "&postId=" + postId;
//这是两个页面,涉及到跨页面传值
});
var delBtnWidth = $(".delBtn").width();
//通过链式语法,一次性绑定三个事件
$(".historyList").on("touchstart", ".historyItem", function (event) {
//现在要判断一根手指
if (event.originalEvent.changedTouches.length == 1) {
//记录一下手指的横坐标 把这个值记录在自定义属性里面
$(this).attr("data-startx", event.originalEvent.changedTouches[0].clientX);
}
}).on("touchmove", ".historyItem", function (event) {
if (event.originalEvent.changedTouches.length == 1) {
//用当前的坐标-之前触摸开始的坐标
var length = event.originalEvent.changedTouches[0].clientX - parseFloat($(this).attr(
"data-startx"));
//判断向左还是向右
if (length < 0) {
if (Math.abs(length) > delBtnWidth) {
length = delBtnWidth * (-1);
}
//说明向左在滑
$(this).css("left", length + "px");
} else if (length > 0) {
//只要我发现你向右滑
$(this).css("left", "0px");
}
}
}).on("touchend", ".historyItem", function (event) {
if (event.originalEvent.changedTouches.length == 1) {
var length = event.originalEvent.changedTouches[0].clientX - parseFloat($(this).attr(
"data-startx"));
if (length < 0) {
//向左
if (Math.abs(length) > delBtnWidth / 2) {
length = delBtnWidth * (-1);
} else {
length = 0;
}
$(this).css("left", length + "px");
} else if (length > 0) {
//向右
$(this).css("left", "0px");
}
}
});
//绑定左滑以后的删除按钮事件
$(".historyList").on("click", ".delBtn", function () {
layer.confirm("你确定要删除这条记录", function (a) {
//代表用户点击确定 a代表当前弹窗的序号
layer.close(a); //关闭当前这个序号的弹窗
var postId = $(this).prev(".historyItem").data("postid");
var kdHistory = JSON.parse(localStorage.getItem("kdHistory"));
var index = kdHistory.map(function (item, index, a) {
return item.postId; //返回快递编号
}).indexOf(postId);
kdHistory.splice(index, 1);
//把删除以后的数据重新放回缓存里面去
localStorage.setItem("kdHistory", JSON.stringify(kdHistory));
//重新渲染模板
$(".historyList").renderTpl("historyItemTemp", {
kdHistory: kdHistory
});
})
})
});
</script>
</html>
history.css代码
@charset "utf-8";
.historyList{
background-color: white;
}
.historyList li{
border-bottom: 1px solid #ececec;
background-color:white;
position:relative;
}
.historyList li .historyItem .top{
display: flex;
font-size: .24rem;
justify-content: space-between;
}
.historyList li .historyItem .bottom{
font-size: .28rem;
margin-top: .2rem;
}
.historyList li .historyItem .top span:first-child{
font-weight:bold;
}
/*删除按钮怎么做*/
.delBtn{
background-color:red;
width: 1.2rem;
position: absolute;
right:0px;
top:0px;
height:100%;
display:flex;
justify-content:center;
align-items:center;
color:white;
font-size:.28rem;
/* z-index:-1; */
}
.historyItem{
padding: .2rem;
background-color: white;
position: relative;
z-index: 1;
transition: all 0.1s linear;
}
在完成历史记录页的时候,要注意这里面的左滑删除功能 ,该功能是移动端常见的效果功能
案例总结
本案例为基础案例,使用的技术与锻炼的能力有以下几点
- jQuery
- 移动端布局
- Ajax
- 请求地址与请求参数
- 学会了看
API
文档 - 缓存的练习
- 跨页面的传值
URLSearchParams
- 模板引擎的使用
- 事件委托的应用场景
- layer.js的初步使用
- jQuery扩展方法的应用
- iconfont的使用
- 触摸实现在滑删除
- CSS移动端取消高亮,以及下拉框去掉箭头
- jQuery的event找到原始事件
- JSON的转换 JSON.parse与JSON.stringify
评论区