Home  >  Article  >  Web Front-end  >  How to write a province and city selector using javascript

How to write a province and city selector using javascript

PHPz
PHPzOriginal
2023-04-24 15:48:221123browse

More and more websites and applications need to take into account the user's province and city selection. Providing a user-friendly province and city selector can not only improve the user's operating experience, but also improve the user satisfaction of the website. This article will describe how to use JavaScript to write a province and city selector and optimize it.

1. Demand analysis

According to the province selected by the user, dynamically display the list of urban areas under the province to complete the selection of province and city cascades. At the same time, the following functions need to be implemented:

  1. The province and city information last selected by the user is displayed by default (if any).
  2. Support users to manually enter province and city names for selection.
  3. Support asynchronous loading of provincial and municipal data to avoid long page response time.

2. Data preparation

In order to implement the province and city selector, we need to prepare the corresponding data first. You can use third-party data sources, such as Alibaba's province and city data (http://lbs.amap.com/api/javascript-api/download/), or you can organize the data yourself. This article uses Alibaba’s data source as an example.

The data source contains two files, namely province.json and city.json. The province.json file records the name and number information of all provinces. The city.json file records the names, province numbers and city number information of all cities. It should be noted here that the city number of each province starts from 1.

3. Interface design

Based on demand analysis, we need to design the selector interface first. You can use a form similar to the input drop-down list to display the list of provinces and cities, and dynamically display the list of cities under the province when the user selects the province. We can use CSS to set the style. The specific code is as follows:

<style>
  .city-selector {
    position: relative;
    display: inline-block;
    font-size: 14px;
  }
  .city-selector input {
    border: 1px solid #ccc;
    width: 200px;
    padding: 5px;
    outline: none;
    box-sizing: border-box;
  }
  .city-selector .dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    border: 1px solid #ccc;
    border-top: none;
    background-color: #fff;
    width: 200px;
    max-height: 200px;
    overflow-y: scroll;
    z-index: 1;
  }
  .city-selector .dropdown li {
    padding: 5px;
    cursor: pointer;
  }
  .city-selector .dropdown li:hover {
    background-color: #f5f5f5;
  }
  .city-selector .dropdown li.selected {
    background-color: #f5f5f5;
    font-weight: bold;
  }
</style>
<div class="city-selector">
  <input type="text" placeholder="请选择省份">
  <ul class="dropdown"></ul>
</div>

4. Implement province selection

First, we need to dynamically load province.json data to the page and render all provinces List of names. When the user enters content in the input box, we need to dynamically match the corresponding province through javascript and render the matched province name into the drop-down list.

<script>
  // 定义全局变量,保存province.json数据
  var PROVINCES = [];
  // 加载province.json数据
  fetch('province.json')
    .then(response => response.json())
    .then(data => {
      PROVINCES = data;
      renderProvinces();
    });
  // 渲染所有省份到下拉列表中
  function renderProvinces() {
    var dropdown = document.querySelector('.city-selector .dropdown');
    // 先清空下拉列表
    dropdown.innerHTML = '';
    // 循环province.json数据,渲染省份名称
    PROVINCES.forEach(province => {
      var li = document.createElement('li');
      li.textContent = province.name;
      li.dataset.id = province.id; // 将省份编号存储在data-id中
      dropdown.appendChild(li);
    });
  }
  // 监听用户输入事件,动态匹配省份名称
  document.querySelector('.city-selector input').addEventListener('input', function() {
    var inputValue = this.value.trim();
    if (inputValue === '') {
      renderProvinces();
      return;
    }
    var dropdown = document.querySelector('.city-selector .dropdown');
    var filteredProvinces = PROVINCES.filter(province => province.name.indexOf(inputValue) >= 0);
    dropdown.innerHTML = '';
    filteredProvinces.forEach(province => {
      var li = document.createElement('li');
      li.textContent = province.name;
      li.dataset.id = province.id;
      dropdown.appendChild(li);
    });
  });
</script>

5. Implement city cascade selection

Next, we need to implement the city cascade selection function. When the user selects a province, we need to dynamically load the list of cities under the corresponding province and display it in the drop-down list.

<script>
  // 监听用户选择省份事件,动态加载相应的城市列表
  document.querySelector('.city-selector .dropdown').addEventListener('click', function(e) {
    var target = e.target;
    if (target.tagName !== 'LI') {
      return;
    }
    // 将用户已选的省份名称和编号存储在input中
    var input = document.querySelector('.city-selector input');
    input.value = target.textContent;
    input.dataset.id = target.dataset.id;
    // 加载相应省份下的城市列表
    loadCities(target.dataset.id);
  });
  // 加载相应省份下的城市列表
  function loadCities(provinceId) {
    fetch('city.json')
      .then(response => response.json())
      .then(data => {
        var cities = data.filter(city => city.provinceId === provinceId);
        renderCities(cities);
      });
  }
  // 渲染城市列表到下拉列表中
  function renderCities(cities) {
    var dropdown = document.querySelector('.city-selector .dropdown');
    // 先清空下拉列表
    dropdown.innerHTML = '';
    // 循环city.json数据,渲染城市名称
    cities.forEach(city => {
      var li = document.createElement('li');
      li.textContent = city.name;
      li.dataset.id = city.id; // 将城市编号存储在data-id中
      dropdown.appendChild(li);
    });
  }
</script>

6. Optimize the selector

After implementing the province and city selector, we need to consider how to further optimize the selector to improve the user's operating experience and page performance.

  1. Support users to manually enter province and city names for selection

When entering province and city names in the input box for matching, we can set a delay for the input box to avoid user input The speed is too fast, causing the page to not respond in time. At the same time, we can also set up a caching mechanism to avoid loading the same data repeatedly.

<script>
  var PROVINCES = [];
  var CITIES = {};
  var debounceTimer = null;
  // 加载province.json数据
  function loadProvinces() {
    fetch('province.json')
      .then(response => response.json())
      .then(data => {
        PROVINCES = data;
      });
  }
  // 动态匹配省份
  function filterProvinces(inputValue) {
    var dropdown = document.querySelector('.city-selector .dropdown');
    var filteredProvinces = PROVINCES.filter(province => province.name.indexOf(inputValue) >= 0);
    dropdown.innerHTML = '';
    filteredProvinces.forEach(province => {
      var li = document.createElement('li');
      li.textContent = province.name;
      li.dataset.id = province.id;
      dropdown.appendChild(li);
    });
  }
  // 监听用户输入事件
  document.querySelector('.city-selector input').addEventListener('input', function() {
    var inputValue = this.value.trim();
    if (debounceTimer) {
      clearTimeout(debounceTimer);
    }
    if (inputValue === '') {
      renderProvinces();
      return;
    }
    debounceTimer = setTimeout(function() {
      if (PROVINCES.length === 0) {
        loadProvinces();
      } else {
        filterProvinces(inputValue);
      }
    }, 300);
  });
  // 监听用户选择省份事件,动态加载相应的城市列表
  document.querySelector('.city-selector .dropdown').addEventListener('click', function(e) {
    var target = e.target;
    if (target.tagName !== 'LI') {
      return;
    }
    var input = document.querySelector('.city-selector input');
    input.value = target.textContent;
    input.dataset.id = target.dataset.id;
    var provinceId = target.dataset.id;
    if (CITIES[provinceId]) {
      renderCities(CITIES[provinceId]);
    } else {
      loadCities(provinceId);
    }
  });
  // 加载相应省份下的城市列表
  function loadCities(provinceId) {
    fetch('city.json')
      .then(response => response.json())
      .then(data => {
        var cities = data.filter(city => city.provinceId === provinceId);
        CITIES[provinceId] = cities;
        renderCities(cities);
      });
  }
</script>
  1. Support asynchronous loading of provincial and municipal data

When the page is loaded, we can only load the necessary initial data and put the loading of provincial and municipal data in the background Asynchronous processing. When the user selects a province, we dynamically load the city data of the corresponding province to avoid long page response time.

<script>
  var debounceTimer = null;
  // 加载所有省份到下拉列表中
  function loadProvinces() {
    fetch('province.json')
      .then(response => response.json())
      .then(data => {
        renderProvinces(data);
      });
  }
  // 渲染所有省份到下拉列表中
  function renderProvinces(provinces) {
    var dropdown = document.querySelector('.city-selector .dropdown');
    dropdown.innerHTML = '';
    provinces.forEach(province => {
      var li = document.createElement('li');
      li.textContent = province.name;
      li.dataset.id = province.id;
      dropdown.appendChild(li);
    });
  }
  // 加载相应省份下的城市列表
  function loadCities(provinceId) {
    fetch('city.json')
      .then(response => response.json())
      .then(data => {
        var cities = data.filter(city => city.provinceId === provinceId);
        renderCities(cities);
      });
  }
  // 渲染城市列表到下拉列表中
  function renderCities(cities) {
    var dropdown = document.querySelector('.city-selector .dropdown');
    dropdown.innerHTML = '';
    cities.forEach(city => {
      var li = document.createElement('li');
      li.textContent = city.name;
      li.dataset.id = city.id;
      dropdown.appendChild(li);
    });
  }
  // 监听用户输入事件
  document.querySelector('.city-selector input').addEventListener('input', function() {
    var inputValue = this.value.trim();
    if (debounceTimer) {
      clearTimeout(debounceTimer);
    }
    if (inputValue === '') {
      loadProvinces();
      return;
    }
    debounceTimer = setTimeout(function() {
      fetch('province.json')
        .then(response => response.json())
        .then(data => data.filter(province => province.name.indexOf(inputValue) >= 0))
        .then(filteredData => {
          renderProvinces(filteredData);
        });
    }, 300);
  });
  // 监听用户选择省份的事件
  document.querySelector('.city-selector .dropdown').addEventListener('click', function(e) {
    var target = e.target;
    if (target.tagName !== 'LI') {
      return;
    }
    var input = document.querySelector('.city-selector input');
    input.value = target.textContent;
    input.dataset.id = target.dataset.id;
    loadCities(target.dataset.id);
  });
  // 页面加载时,只加载必要的初始数据
  loadProvinces();
</script>

7. Summary

This article introduces how to use javascript to implement the province and city selector, and how to optimize the selector to improve the user's operating experience and page performance. Implementing a user-friendly province and city selector is not only a technical issue, but also requires taking into account the user's habits and needs, as well as the page's response time and performance issues. We hope this article can provide you with some reference and help.

The above is the detailed content of How to write a province and city selector using javascript. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn