查找城市

268 阅读2分钟

功能描述和最终效果

在搜索框输入文字,自动匹配对应的数据。

效果是这样的:

城市.gif

原版数据包含了美国的城市,数据格式是这样的

[    {        "city": "New York",         "growth_from_2000_to_2013": "4.8%",         "latitude": 40.7127837,         "longitude": -74.0059413,         "population": "8405837",         "rank": "1",         "state": "New York"    },     {    ....    }]

抱着本土化的原则,我在网上找了个中国省市县的数据,数据格式是这样的

[
    {
    "provinceCode": "110000",
    "provinceName": "北京市",
    "provinceType": 1,
    "cities": [
        {
        "cityCode": "110100",
        "cityName": "市辖区",
        "cityType": 1,
        "isCapital": true,
        "counties":[
             {
                "countyCode": "110101",
                "countyName": "东城区",
                "isCity": false
            },
            {
            ...
            }
        ]
    ]
]

接下来查找城市时,会以这个数据为准

样式

利用translate和阴影做出纸张折叠的效果

首先,这是一个普通的li

<li class="result-item">
   <p class="item-code">区域编码</p>
   <p class="item-name">城市名称</p>
</li>

加上阴影

background: linear-gradient(to top, #ffffff 0%, #efefef 100%);

加上特效

transform: perspective(100px) rotateX(-3deg) translateY(3px);

就很好看了

41173C9D-7F09-489e-9943-2CEF402C8F37.png

功能

获取用户输入

由于匹配的数据是中文的,所以需要已确认文本时,才获取用户输入的值。所以不能监听input事件,而是要监听compositionend事件。

input_dom.addEventListener("compositionend", (event) => {
   console.log(event.data);
});

如果想要输入完按下回车再搜索,可以监听change事件

找到匹配的数据

先分析一下city.json:

  • 直辖市、自治区、省份是在一级的,匹配provinceName即可,这三种可以用provinceType区分。
  • 只有自治区和省份需要匹配下一级,即cities下的cityName

于是写出了这样的方法(...)

function getCityList(cname) {
        const list = [];
        city.forEach((item) => {
          if (item.provinceName.includes(cname)) {
            list.push({ name: item.provinceName, code: item.provinceCode });
          }
          if (item.provinceType !== 1) {
            item.cities.forEach((i) => {
              if (i.cityName.includes(cname)) {
                list.push({ name: i.cityName, code: i.cityCode });
              }
            });
          }
        });
        return list;
      }

值得一提的是"aaa".includes('')会返回true,也就是说输入一次城市名称进行查找,再把名称全部删除就会显示所有城市的数据(由于我觉得效果还不错,就保留了这个效果)

输出匹配的数据到html上

function addliDom(mlist) {
        let str = "";
        mlist.forEach((item) => {
          str += `<li class="result-item"><p class="item-code">${item.code}</p><p class="item-name">${item.name}</p></li>`;
        });
        ul_dom.innerHTML = html_str + str;
      }