快递案例webSql版

Administrator
发布于 2020-07-24 / 14570 阅读 / 0 评论 / 0 点赞

快递案例webSql版

快递案例webSql版

  • 案例名称:快递案例webSql版
  • 案例人员:杨标
  • 案例平台:HTML+CSS+JavasScript+jQuery+template+iconfont+Ajax
  • 完成时间:2019年9月12日

::: tip 提示
本案例可下载
:::


效果图

image

image

案例说明

在进行这个案例之前,已经有一个 localStorage的版本,可自行去查看,该案例与之前的案例相似,只是将缓存的方式改为了webSql。

希望通过该案例能够对一些常用的Sql操作运用于实际的开发案例当中,同时也为后期的mysql做一个预习,如果各们有时间可以将两个案例下载以后自习研究一下,现将代码贴出

案例代码

该案例的目录结构如下图

1568892982370

主页功能

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/initDB.js" type="text/javascript"></script>
<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 baseURL = "https://www.softeem.xin";
    $(function () {
        //怎么样判断有没有缓存呢
        db.transaction(function (tx) {
            tx.executeSql("select * from kdComList", [], function (tx, result) {
                if (result.rows.length == 0) {
                    //没有绑上,请求
                    $.get(baseURL + "/Api/KuaiDi/getKuaiDiCom", function (data) {
                        kdComList = data;
                        db.transaction(function (tx) {
                            kdComList.forEach(function (item, index, a) {
                                tx.executeSql("insert into kdComList (key,com) values (?,?)", [item.key, item.com]);
                            });
                        })
                        //渲染模板
                        $("#kdType").renderTpl("kdTypeTemp", {
                            kdComList: kdComList
                        });
                    });
                } else {
                    //有缓存
                    kdComList = Array.prototype.slice.call(result.rows);
                    $("#kdType").renderTpl("kdTypeTemp", {
                        kdComList: kdComList
                    });
                }
            });
        });
        $(".btnQuery").click(function () {
            //获取快递类型与快递单号
            var type = $("#kdType").val();
            var postId = $("#postId").val();
            if (type && postId) {
                //现在,这第二个参数代表的是请求参数
                //在GET请求的时候,请求地址与请求参数是可以拼在一起的,也可以像下面这种方式来进行分开
                //jQuery里面的Ajax会自动将我们的参数进行拼接
                $.get(baseURL + "/Api/KuaiDi/getKuaiDiInfo", {
                    type: type,
                    postId: postId
                }, function (data) {
                    $(".resultList").renderTpl("resultListTemp", { traces: data.Traces })
                    //缓存操作
                    db.transaction(function (tx) {
                        tx.executeSql("select * from kdHistory where postId=?", [postId], function (tx, result) {
                            if (result.rows.length == 0) {
                                //没有找到   添加记录
                                //先找到com
                                var com = kdComList.filter(function (item, index, a) {
                                    return item.key == type;
                                })[0].com;
                                //获取快递最后一条信息
                                var lastItem = data.Traces[data.Traces.length - 1];
                                tx.executeSql("insert into kdHistory (com,type,postId,time,lastInfo) values (?,?,?,?,?)", [com, type, postId, new Date().toLocaleString(), lastItem.AcceptTime + " " + lastItem.AcceptStation]);
                            }
                            else {
                                //找到了    修改记录
                                var lastItem = data.Traces[data.Traces.length - 1];
                                tx.executeSql("update kdHistory set time=?,lastInfo=? where postId=?", [new Date().toLocaleString(), lastItem.AcceptTime + " " + lastItem.AcceptStation, postId]);
                            }
                        })
                    })
                });
            }
            else {
                layer.alert("请输入快递单号与选择快递公司");
            }
        });

    })
</script>
</html>

在上面的代码过程当中,我们看到有一个initDB.js这个文件,该文件主要是对webSql做一次初始化,创建webSql数据库与的过程,代码如下

initDB.js代码

var db = openDatabase("bgkuaidi", "1.0", "bgkuaidi", 2 * 1024 * 1024);
//创建一个数据表,用于放快递公司的缓存
db.transaction(function (tx) {
    //创建了第一个数据表,用于存放快递公司的缓存
    tx.executeSql("CREATE TABLE IF NOT EXISTS kdComList (key,com)");
    //创建一个数据表,用于放查询记录
    tx.executeSql("CREATE TABLE IF NOT EXISTS kdHistory (com,type,postId,time,lastInfo)");
});

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;
}

历史记录功能

该页面主要的功能就是将之前的查询记录缓存起来,方便用户以后再次去查询

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/initDB.js" type="text/javascript"></script>
<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 = [];
        var delBtnWidth;
        db.transaction(function (tx) {
            tx.executeSql("select * from kdHistory", [], function (tx, result) {
                //类数组转换成数组
                kdHistory = Array.prototype.slice.call(result.rows);
                //在通过模板引擎去调用
                $(".historyList").renderTpl("historyItemTemp", {
                    kdHistory: kdHistory
                });
                // 默认情况下是没有按钮的,要经过渲染完成以后才会的,所以代码应该写在这个地方
               delBtnWidth = $(".delBtn").width();
            })
        })


        //点击历史记录重新查询
        $(".historyList").on("click", ".historyItem", function () {
            //我们要取到快递类型与快递的单号
            var type = $(this).data("type");
            var postId = $(this).data("postid");
            location.href = "index.html?type=" + type + "&postId=" + postId;
            //这是两个页面,涉及到跨页面传值

        });



        
        
        //通过链式语法,一次性绑定三个事件
        $(".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 () {
            var that=this;
            layer.confirm("你确定要删除这条记录", function (a) {
                //代表用户点击确定  a代表当前弹窗的序号
                layer.close(a); //关闭当前这个序号的弹窗
                var postId = $(that).prev(".historyItem").data("postid");
                db.transaction(function(tx){
                    tx.executeSql("delete from kdHistory where postId=?",[postId.toString()],function(tx,result){
                        location.reload();
                    }); 
                });
            })
        });
    });
</script>
<!--
    1.webSql的使用,重温SQL语句
    2.Ajax请求的参数可以使用对象的方式来进行,jQuery自动帮我们拼接【GET请求】
      对象这种情况下面的参数是既可以在GET下面使用,也可以在POST下面使用
    $.get(url,{},function(data){})
    $.get(url?请求参数,function(data){});
    $.post(url,{},function(data){});   //POST如果有参数,只能这么写
    3.注意this的情况,注意页面加载的情况
      通过模板生成的DOM,你应该是先等模板生成完了以后,再进行这些DOM操作
-->
</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;
}

案例总结

本案例为基础案例,与之前的localStorage版本相对比,主要的学习点在以下几个方面

  1. webSql的使用,重温SQL语句

  2. Ajax请求的参数可以使用对象的方式来进行,jQuery自动帮我们拼接【GET请求】

    对象这种情况下面的参数是既可以在GET下面使用,也可以在POST下面使用

    $.get(url,{},function(data){})
    $.get(url?请求参数,function(data){});
    $.post(url,{},function(data){}); //POST如果有参数,只能这么写

  3. 注意this的情况,注意页面加载的情况
    通过模板生成的DOM,你应该是先等模板生成完了以后,再进行这些DOM操作

总之,两个版本都是做的同一个案例,其中80%的代码是相同的,但是有些地方换了一种方式再写,各个可以仔细对象一下,特别是在缓存操作webSql以及Ajax请求的时候


评论