web學習筆記15-移動端地址選擇控件-v1.0簡單版

    很久都沒有寫東西了,如今乾的活都是重複和簡單的活,能總結出來的東西仍是不太多。css

    目前作電商平臺,其中用到選擇地址的控件,不過不是本身寫的,最近花時間從新本身作一個,目前就先吧功能樣式,功能完成初版,以後再進行優化和升級,最終作成組件或者是插件形式,調用只須要幾行代碼去完成,不過這些都是後話了,目前顯示完成基本的樣子和功能。這一篇文章就當作寫東西的一個筆記,記錄一個過程。html

    先放上出來的效果
成果gifvue

    看效果圖挺簡單的,由於懶。就用了jquery加js,方法什麼的也沒考慮性能啥的,就初步先作一個出來。後面再慢慢一步步優化。jquery

    不肯意往下看的有興趣的能夠直接看這裏 githubd selectAddress-v1.0地址git

    接下來咱們進入正題!有什麼問題能夠留言跟我討論,這個功能不是很複雜,只是做爲粗糙版就沒有考慮不少。github

    接下來咱們進入正題!有什麼問題能夠留言跟我討論,這個功能不是很複雜,只是做爲粗糙版就沒有考慮不少。web

第一步:構思功能樣子,先有概念!

    首先至少得有想法,作成什麼樣子,這個很重要,要是會點設計,能夠本身先作個大概的圖或者原型,既然以後要作成組件,首先頁面上就得有個按鈕,而後彈出選擇地址的彈框,頁面上得有一個顯示選擇完地址的標籤。ajax

    彈框出來以後,得有幾個部分,一個是頂部標題,叉叉按鈕用來隱藏,接下來是每級選擇完的地址顯示在中間,而後就是下面的每級地址列表,而且列表中如有選中的地址則標紅,這些都是最基本的。json

    我這邊作的地址目前只有四級地址,不會有更深層次的地址,因此只有四列。構思好了,大概樣子就是下圖。數組

第二步:構思完以後就是構造頁面

    構造頁面算是最簡單的部分了,就是寫html,css了。寫成上圖的樣子。

    由於四級地址列表考慮到屢次切換留有緩存的問題,沒有作成每切換一次就請求一次,而是作成四個列表,經過隱藏顯示的方式來更方便的操做。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,minimum-scale=1, maximum-scale=1"/>
    <link rel="stylesheet" href="address.css">
    <script src="jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="btn" onclick="show()">點擊選擇地址</div>

<div class="show_address" id="product_address_show" onclick="show()">北京市,北京市,朝陽區,朝外街道</div>

<div id="yls_address_choose" style="display: none">
    <div class="yls_address_bg" onclick="hide()"></div>
    <div class="yls_address_main">
        <div class="yls_address_pop_top">
            <div class="yls_address_pop_title">請選擇地址</div>
            <div class="yls_address_pop_cancel" onclick="hide()"></div>
        </div>
        <div class="yls_address_pop_main">
            <div class="yls_address_product">
                <div class="yls_address_select" id="yls_address_select">
                    <div class="yls_address_top_address jdshop_alignment_middle">
                        <div id="yls_top_address_1">請選擇</div>
                        <div id="yls_top_address_2"></div>
                        <div id="yls_top_address_3"></div>
                        <div id="yls_top_address_4"></div>
                    </div>
                    <div class="yls_address" id="yls_address_1"></div>
                    <div class="yls_address" id="yls_address_2"></div>
                    <div class="yls_address" id="yls_address_3"></div>
                    <div class="yls_address" id="yls_address_4"></div>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

    這個html仍是一目瞭然的,很簡單,下面是css樣式。

body, html {
    -webkit-user-select: none;
    user-select: none
}
html {
    -webkit-text-size-adjust: 100%
}
body {
    line-height: 1.6;
    background-color: #f5f5f9;
    color: #4a4a4a;
    font-size: 14px;
    font-family: Arial, '微軟雅黑', Helvetica Neue, Helvetica, sans-serif;
    -webkit-overflow-scrolling: touch;
    overflow-scrolling: touch
}
* {
    margin: 0;
    padding: 0
}
a img {
    border: 0
}
a {
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    -webkit-appearance: none
}
@font-face {
    font-weight: 400;
    font-style: normal;
    font-size: 14px;
    font-family: Arial, '微軟雅黑', Helvetica Neue, Helvetica, sans-serif
}
input, textarea {
    border: 0;
    outline: 0;
    -webkit-appearance: none;
    -webkit-tap-highlight-color: transparent;
    font-size: inherit;
    color: inherit
}

/*點擊選擇按鈕*/
.btn{
    margin: 0 auto;
    width: calc(50%);
    height: 30px;
    margin-top: 100px;
    background-color: lightcyan;
    line-height: 30px;
    text-align: center;
    font-size: 14px;
}
.alignment_middle{
    -webkit-box-align: center;
    -webkit-align-items: center;
    align-items: center;
    -webkit-box-pack: start;
    -webkit-justify-content: flex-start;
    justify-content: flex-start;
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
}
/*顯示文字*/
.show_address{
    margin: 0 auto;
    margin-top: 10px;
    width: 80%;
    height: 30px;
    background-color: #fff;
    text-align: center;
    line-height: 30px;
    font-size: 14px;
}

/*背景*/
.yls_address_bg {
    position: fixed;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    background: #000;
    z-index: 500;
    opacity: .3;
    -webkit-transition: opacity .3s;
    transition: opacity .3s;
    touch-action: none
}
/*主彈框*/
.yls_address_main {
    position: fixed;
    left: 0;
    width: 100%;
    bottom: 0;
    background: #fff;
    border-radius: 10px 10px 0 0;
    box-shadow: 0 0 3px #e9e9e9;
    -webkit-transform: translate3d(0, 120%, 0);
    transform: translate3d(0, 120%, 0);
    -webkit-transition: -webkit-transform .3s;
    transition: -webkit-transform .3s;
    transition: transform .3s;
    transition: transform .3s, -webkit-transform .3s;
    z-index: 1001;
    transform: translate3d(0, 0, 0);
}
.yls_address_pop_top {
    text-align: center;
    height: 50px;
    margin-bottom: 5px;
}
.yls_address_pop_title {
    height: 100%;
    line-height: 50px;
}
.yls_address_pop_cancel {
    position: absolute;
    right: 0;
    top: 0;
    width: 50px;
    height: 50px;
}
.yls_address_pop_cancel::before, .yls_address_pop_cancel::after {
    content: '';
    width: 16px;
    height: 1px;
    background: #000;
    display: block;
    position: absolute;
    right: 10px;
    top: 25px;
}
.yls_address_pop_cancel::before {
    transform: rotate(45deg); /*進行旋轉*/
}
.yls_address_pop_cancel::after {
    transform: rotate(-45deg);
}
.yls_address_pop_main {

}
.yls_address_product{

}
.yls_address_select{
    height: calc(60vh);
    width: 100%;
    position: relative;
    overflow: hidden;
}
.yls_address_top_address{
    font-size: 12px;
    height: 35px;
    overflow: hidden;
    border-bottom: 1px solid #ddd;
}
.yls_address_top_address>div{
    padding: 5px 5px;
    margin: 0 5px;
    white-space: nowrap;
}
.yls_address_top_address>div.show{
    color: #c91623;
    border-bottom: #c91623 1px solid;
}
.yls_address{
    position: absolute;
    left: 0;
    top: 45px;
    overflow: auto;
    width: 100%;
    height: calc(60vh - 35px);
    -webkit-transform: translate3d(-100%,0,0);
    transform: translate3d(-100%,0,0);
    -webkit-transition: -webkit-transform .3s .2s;
    transition: -webkit-transform .3s .2s;
    transition: transform .3s .2s;
    transition: transform .3s .2s,-webkit-transform .3s .2s;
}
.yls_address p{
    padding: 8px 10px;
    font-size: 14px;
}
.yls_address p.p_show {
    position: relative;
    color: #c91623;
}
.yls_address.show {
    -webkit-transform: translate3d(0,0,0);
    transform: translate3d(0,0,0);
}

    css上半部分是一些基本的初始化瀏覽器樣式,下面部分就是地址選擇的樣式,目前還沒加入動態效果,以後優化部分考慮作進去。不過這部分的樣式徹底能夠本身按照本身的喜愛作,想作成什麼樣子就作成什麼樣子的。

第三步 :邏輯部分

    這個部分算是最重要的,不過在此重申一遍,我作的只是粗糙的版本,邏輯部分是沒有通過任何優化的,這個你們能夠按照本身優化的方式進行優化,後期我會作成插件形式再寫一篇。😂但願看到這篇文章的你們不要嘲笑我寫的粗糙,畢竟我寫這個也只是給新手看看,不要嫌棄。

1.作基本的變量聲明工做

/*賦初始值*/
    var startId = [1804,1805,1829,1831];
    var startName = ['北京市','北京市','朝陽區','朝外街道'];

    //最終獲取到的值
    var returnStartId = [];
    var returnStartName = [];

2.作彈出彈框的彈出隱藏方法

/*顯示地址選擇,隱藏地址選擇*/
    function show() {
        document.getElementById("yls_address_choose").style.display="";//顯示
        var url = 'http://*********/address/areas?areaId=';//這邊寫你請求接口的url
        initAddress(url,startId,startName);//初始化工做的方法
    }

    /*隱藏地址選擇*/
    function hide() {
    //點擊隱藏的時候循環將列表全部的show樣式去除,從新添加到最後一列上
        for(var i = 1;i < 5;i++){
            var ad = 'yls_top_address_' + i;
            var adid = 'yls_address_' + i;
            $("#"+ad).removeClass('show');
            $("#"+adid).removeClass('show');
            $("#"+ad).show();
            $("#"+adid).show();
        }
        document.getElementById("yls_address_choose").style.display="none";//顯示
        //點擊隱藏了,就把最終值還原成初始值
        returnStartId = startId;
        returnStartName = startName;
    }

3.作彈出彈框的初始化工做

//初始化方法
    function initAddress(url,startId,startName) {
        //將咱們最後須要獲取的值初始化成初始值
        returnStartId = startId;
        returnStartName = startName;
        //初始化請求areaid=0的數據,我用的接口areaid=0的時候是請求省級地址
        request(url,0,1);
    }

     //初始化請求數據部分,
    //thisNum 爲areaid變化數值 url是請求url, addressNum是每一個address是第幾個
    function request(url,thisNum,addressNum){
        var addressUrl = url+ thisNum;
        $.ajax({
            type: 'get',
            url: addressUrl,
            dataType: "json",
            success: function (res) {
                //無常規錯誤,根絕data數據作具體的業務判斷顯示
                console.log(res.result);
                //初始化的渲染html
                setHtml(res.result,thisNum,addressNum);
                //循環請求下級地址
                if(addressNum < startId.length){
                    request(url,startId[addressNum-1],addressNum+1);
                    addressNum += 1;
                }
            },
            error: function erryFunction(err) {
                //網絡請求錯誤
                console.log(err);
                console.log('讀取失敗')
            }
        });
    }

    //初始化渲染頁面
    function setHtml(data,thisNum,addressNum) {
        var addressId = 'yls_address_' + addressNum;
        var topAddress = 'yls_top_address_' + addressNum;
        if(addressNum == startId.length){
            $("#"+addressId).addClass('show');
            $("#"+topAddress).addClass('show');
        }
        $("#"+topAddress).text(startName[addressNum-1]);

        //初始化以後選中的地址頂部tab進行添加點擊方法,每次點擊會作什麼事情
        document.getElementById(topAddress).addEventListener("click",function () {
            var a = parseInt(topAddress.substr(topAddress.length-1,1));
            console.log(a);
            for(var i = 1;i < 5;i++){
                var ad = 'yls_top_address_' + i;
                var adid = 'yls_address_' + i;
                if(i != a){
                    $("#"+ad).removeClass('show');
                    $("#"+adid).removeClass('show');
                    if(i > a){
                        $("#"+ad).hide();
                    }
                }else{
                    $("#"+ad).addClass('show');
                    $("#"+adid).addClass('show');
                }
            }

            //tab上選中地址點擊的時候,最終選擇地址數組數據也要相應的變化
            returnStartId = returnStartId.slice(0,addressNum);
            returnStartName = returnStartName.slice(0,addressNum);
           
        },false);
        $("#"+addressId).empty();//清空當前列表的html
        var html = '';
        //拼接html,爲地址列表中每個地址添加點擊方法
        if(data){
            for(var i = 0;i < data.length;i++){
                if(startName[addressNum-1] == data[i].name){
                    html += '<p class="p_show" id="add_'+data[i].areaId+'" onclick="chooseDetail('+data[i].areaId+','+addressNum+',&quot;'+data[i].name+'&quot;)">'+data[i].name+'</p>';
                }else{
                    html += '<p id="add_'+data[i].areaId+'" onclick="chooseDetail('+data[i].areaId+','+addressNum+',&quot;'+data[i].name+'&quot;)">'+data[i].name+'</p>';
                }
            }
        }
        //添加html到列表上渲染頁面
        $("#"+addressId).append(html);
    }

4.每次點選地址以後的具體邏輯

//點擊列表中詳細地址的方法
    function chooseDetail(areaId,addressNum,name) {
        var url = 'http://******/address/areas?areaId=';
        var adid = 'add_'+areaId;
        var adid1 = 'yls_address_' + addressNum;
        //選中的數據加上標紅顯示
        $("#"+adid1+'>p').removeClass('p_show');
        $("#"+adid).addClass('p_show');

        //點擊具體地址以後,將最終選擇地址數組中相應位置的數據替換掉
        returnStartId[addressNum-1] = areaId;
        returnStartName[addressNum-1] = name;
        
        //判斷是不是第四級地址,若是是第四級地址,把獲取到的數據渲染到頁面上,而且隱藏彈框
        //若是是第四級地址,發送請求獲取下一級的數據進行渲染頁面
        if(addressNum == 4){
            var topAddress1 = 'yls_top_address_' + addressNum;
            $("#"+topAddress1).text(name);
            $("#product_address_show").text(returnStartName);
            hide();
        }else{
            newrequest(url,areaId,addressNum,name);
        }
    }


    //點擊列表裏具體地址,發送新的請求獲取下一級數據
    //thisNum 爲areaid變化數值 url是請求url, addressNum是每一個address是第幾個,name是你選擇的地址具體名稱
    function newrequest(url,thisNum,addressNum,name){
        var addressUrl = url+ thisNum;
        $.ajax({
            type: 'get',
            url: addressUrl,
            dataType: "json",
            success: function (res) {
                //無常規錯誤,根絕data數據作具體的業務判斷顯示
                console.log(res.result);
                //獲取到數據以後渲染下一級列表
                setHtml2(res.result,thisNum,addressNum,name);
            },
            error: function erryFunction(err) {
                //網絡請求錯誤
                console.log(err);
                console.log('讀取失敗')
            }
        });

    }

    //選擇詳細地址請求獲取數據以後渲染方法
    function setHtml2(data,thisNum,addressNum,name) {
        //獲取到相應的div
        var adid1 = 'yls_address_' + addressNum;
        var adid2 = 'yls_address_' + (addressNum+1);
        var topAddress1 = 'yls_top_address_' + addressNum;
        var topAddress2 = 'yls_top_address_' + (addressNum+1);

        //清空相應的下一級div和下一級tab上選中的地址,填入新的數據
        $("#"+topAddress2).empty();
        $("#"+adid2).empty();
        $("#"+topAddress2).addClass('show');
        $("#"+topAddress2).show();
        $("#"+topAddress1).removeClass('show');
        $("#"+adid2).addClass('show');
        $("#"+adid1).removeClass('show');
        $("#"+topAddress2).text('請選擇');
        $("#"+topAddress1).text(name);
        var html = '';
        if(data){
            //拼接html,而且添加上新的詳細地址選擇方法
            for(var i = 0;i < data.length;i++){
                html += '<p id="add_'+data[i].areaId+'" onclick="chooseDetail('+data[i].areaId+','+(addressNum+1)+',&quot;'+data[i].name+'&quot;)">'+data[i].name+'</p>';
            }
        }
        $("#"+adid2).append(html);
    }

    以上三步就完成了地址選擇粗糙版的構造,其中用來請求數據的方法寫了兩個,拼接html渲染頁面的方法也寫了兩個,這些是有點冗餘的,這個部分以後能夠合成一個。

    目前優化的構思是有,不過還沒來得及實施,得找時間作一下,優化的思路是其中的方法先進行相應的優化,最後集成成一個對象,在頁面調用的時候只要把初始化數據傳入,最後加上一個回調方法,將選擇完成的地址返回回來,這樣整個頁面也呢個簡潔不少,調用方法也簡單了,使用起來的話會方便不少。

    由於目前我寫的vue的單頁面應用,用到keepAlive,因此現有的控件老是出問題,等這兩天優化完進行測試下,到時候在寫一篇簡單點的文章發佈出來。

    能看到這裏的,你們要是有什麼問題的能夠留言跟我討論討論,有啥好的想法也能夠跟我溝通,你們一塊兒學習。

以上

相關文章
相關標籤/搜索