適應移動端的地址四級(省市區街道)聯動選擇


首先推薦兩款個人比較優秀的控件:

一、https://huangchanghuan.github.io/city-picker/  

這個是由 city-picker 控件(npm 安裝方法: npm install city-picker),地址三級改造而來,數據由京東數據庫提供。

優點:

1. 樣式比較容易自定義;

2. 對省級地址按字母進行了區分,直觀了然。

缺點:

1. 儲存地址數據的文件,省市區街道四級在一個文件里,該文件接近 1M ,比較耗費流量;

2. 數據是由京東數據庫提供,如果京東的地址數據庫有更改,還需要手動進行更新。

二、http://jquerywidget.com/jquery-citys/

該地址數據庫來源 http://passer-by.com/data_location/list.json ,由統計局最新數據同步。

優點:

1. 地址數據更新容易,能獲取到統計局的最新數據;

2. 街道地址異步調用,根據不同的三級(區縣)分為了多個 json 文件,文件較小。

缺點:

1. 默認樣式比較適合電腦端,移動端需要更改 select 和 option 標簽為其他標簽(如:ul li),樣式難以調整;

2. 需要更改源 js 文件比較多。

 

最近開發的項目中就是使用的第二個控件,來做的調整,項目運行在微信公眾號中。下面詳細介紹下步驟和源碼分析

源碼下載和介紹地址:https://github.com/xinjie-just/address-select.git

演示地址

效果圖在 iPhone6 模擬機下演示:

圖1. 初始化頁面,未打開地址選擇器時:

圖2:地址選擇器打開,待選擇省級時:

 圖三:街道地址加載中:

圖四:回顯

 源碼分析:

<label for="Addr" id="areaLabel" class="address">
    <span>所在地區</span>
    <input type="text" name="Addr" id="Addr" readonly placeholder="請選擇地區">
</label>
<div id="addressSelectWrapper">
    <div id="addressSelect">
        <div class="tip">
            <h3>所在地區</h3>
            <button type="button" id="cancel"></button>
        </div>
        <div id="address">
            <ul class="selected-address">
                <li class="lastarea" id="lastprovince">請選擇</li>
                <li class="lastarea" id="lastcity">請選擇</li>
                <li class="lastarea" id="lastarea">請選擇</li>
                <li class="lastarea" id="lasttown">請選擇</li>
            </ul>
            <div class="address-content">
                <ul id="province"></ul>
                <ul id="city"></ul>
                <ul id="area"></ul>
                <ul id="town"></ul>
            </div>
        </div>
    </div>
</div>
1. label#areaLabel 是用來顯示地址和打開地址選擇器的標簽。
2. div#addressSelectWrapper 是用來存放整個地址選擇器的容器。
3. div#addressSelect 是用來選擇地址的容器,占 div#addressSelectWrapper 高度比例 70%。
4. div.tip 作為標題提示,包含有關閉按鈕。
5. ul.selected-address 作為待選擇地址提示和回顯地址的列表
6. div.address-content 全部地址以及異步調用的街道地址的顯示容器。

根據后期的優化和踩過的坑,對 js 源碼部分解釋:

一、在數據處理的市級數據處理時,如果按照以下選擇會出現 bug

1. 選擇直轄市 -> 2. 重新選擇非直轄市的省級 -> 3. 選擇任意一個城市

這種情況下,選擇任意一個城市,它下面的區縣級地址都是第一個城市的區縣地址。

例如:

1. 選擇北京市 -> 2. 重新選擇四川省 -> 3. 選擇四川省下的任意一個城市

它下面的區縣都是第一個城市"成都"的區縣

自貢市下面本該有自流井區、貢井區等,結果出現了成都市(排在第一位置的城市)的錦江區,青羊區等。

 

出現這個 bug 原因是選擇直轄市后,在選擇其它非直轄市的省級,沒有重置 hasCity 的值,使其變為非直轄市。 hasCity = true 

//市級數據處理
city: function () {

    try {
        toolHanlder.showContent(2);
        toolHanlder.showLoading();
        toolHanlder.createHtml(2);

        //由於存在直轄市的問題,所以這里需要對市區進行特殊處理
        var len = $city.find("li").length;
        if (!len) {
            hasCity = false;
            $lastCity.hide();
            $city.hide();
            dataHanlder.area();
        } else {
            hasCity = true;   // 重置,使它表示非直轄市。否者如果先點擊直轄市后,這里的值會是先前點擊的直轄市,即 hasCity = false;
            // 選擇城市
            $city.find("li")
                .click(function() {
                    var $this = $(this);
                    toolHanlder.liClick($this, 2);
                });
        }
    } catch (e) {
        console.log(e.message);
    } finally {
        toolHanlder.hideLoading();
    }

},

 

二、顯示動畫

在選擇區縣級地址后,將會調用該區縣下的街道地址,如果網絡慢的原因將會導致加載時間過長,中間有一些停頓的時間用戶不知道接下來的操作流程。

//顯示加載動畫
showLoading: function() {
    $container.find("div.address-content").append('<div class="loading">加載中</div>');
},
//隱藏加載動畫
hideLoading: function() {
    $container.find("div.loading").remove();
},

在每一級數據處理中,都去調用該方法顯示加載動畫,待數據加載完成后再隱藏加載動畫。

 

三、為當前待地址特殊標記

給“作為待選擇地址提示和回顯地址的列表項 li.lastarea ”添加 active 類

//顯示地區選擇區域
showContent: function(level) {
    //顯示對應的區域選擇框

    //先移除所有的選擇效果
    $lastProvince.siblings().addBack().removeClass('active');   // lxj, 上次成功選擇的省級區域,去除同級別的li的樣式
    $province.siblings().addBack().hide();    // lxj, 當前的省級選擇,將同級別的影藏

    switch (level) {
    case 1:
        {
            $lastProvince.addClass('active').show();
            $province.show();
        }
        break;
    case 2:
        {
            $lastCity.addClass('active').show();
            $city.show();
        }
        break;
    case 3:
        {
            $lastArea.addClass('active').show();
            $area.show();
        }
        break;
    case 4:
        {
            $lastTown.addClass('active').show();
            $town.show();
        }
        break;
    }
},

如“顯示地址選擇區域”中,在每一級待要選擇的地址中添加 active 類  $lastCity.addClass('active') 

 

更多說明及解釋,查看 https://github.com/xinjie-just/address-select.git README.md。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM