zoukankan      html  css  js  c++  java
  • 适应移动端的地址四级(省市区街道)联动选择

    首先推荐两款个人比较优秀的控件:

    一、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。

  • 相关阅读:
    Java-常用类、接口关系图谱
    Java基础语法09-面向对象下-内部类-注解-异常
    Java基础语法08-面向对象-枚举-包装类-接口
    Java-常用类、接口API
    Docker学习系列(三)Docker搭建gitlab的两种方式
    Docker学习系列(二)Docker初体验
    Docker学习系列(一)Docker简介
    ZooKeeper介绍与环境搭建
    JDK工具系列之jps
    Mycat数据库中间件对Mysql读写分离和分库分表配置
  • 原文地址:https://www.cnblogs.com/xinjie-just/p/7444361.html
Copyright © 2011-2022 走看看