首頁  >  文章  >  web前端  >  如何使用javascript寫一個省市選擇器

如何使用javascript寫一個省市選擇器

PHPz
PHPz原創
2023-04-24 15:48:221123瀏覽

越來越多的網站和應用程式需要考慮到用戶的省市選擇問題。提供一個使用者友善的省市選擇器不僅可以提高使用者的操作體驗,還能提高網站的使用者滿意度。本文將講述如何使用javascript撰寫一個省市選擇器,並對其進行最佳化。

一、需求分析

根據使用者選擇的省份,動態展示該省份下的市區列表,完成省市級聯的選擇。同時,需要實現以下功能:

  1. 預設展示用戶上一次選擇的省市資訊(如果有)。
  2. 支援使用者手動輸入省市名稱進行選擇。
  3. 支援省市資料的非同步加載,避免頁面回應時間過長。

二、資料準備

為了實現省市選擇器,我們需要先準備好對應的資料。可以使用第三方資料來源,如阿里巴巴的省市區資料(http://lbs.amap.com/api/javascript-api/download/),也可以自己整理資料。本文使用阿里巴巴的資料來源為例。

資料來源包含兩個文件,分別是province.json和city.json。其中province.json文件記錄了所有省份的名稱和編號資訊。 city.json檔案記錄了所有城市的名稱、所屬省份編號和城市編號資訊。這裡要注意的是,每個省份的城市編號是從1開始計數的。

三、介面設計

根據需求分析,我們需要先設計好選擇器的介面。可以使用類似於input下拉列表的形式展示省市列表,並在用戶選擇省份時動態展示該省份下的城市列表。我們可以使用CSS來進行樣式的設置,具體代碼如下:

<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>

四、實現省份選擇

首先,我們需要向頁面動態加載province.json數據,並渲染所有省份的名稱列表。當使用者在輸入框中輸入內容時,我們需要透過javascript來動態匹配對應的省份,並將匹配到的省份名稱渲染到下拉清單中。

<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>

五、實現城市級聯選擇

接下來,我們需要實現城市級聯選擇功能。當使用者選擇省份時,我們需要動態載入相應省份下的城市列表,並顯示在下拉列表中。

<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>

六、實作選擇器的最佳化

實現省市選擇器後,我們需要考慮如何進一步優化此選擇器,提高使用者的操作體驗和頁面的效能。

  1. 支援使用者手動輸入省市名稱進行選擇

在輸入框中輸入省市名稱進行比對時,我們可以為輸入框設定延遲,避免使用者輸入速度過快,導致頁面回應不及時。同時,我們也可以設定快取機制,避免重複載入相同的資料。

<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. 支援省市數據的非同步載入

在頁面載入時,我們可以只載入必要的初始數據,而將省市數據的載入放到後台異步處理。當使用者選擇省份時,我們再動態載入對應省份的城市數據,避免頁面回應時間過長。

<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>

七、總結

本文介紹如何使用javascript實現省市選擇器,以及如何對選擇器進行最佳化,提高使用者的操作體驗和頁面的效能。實現一個用戶友好的省市選擇器不僅是技術問題,還需要考慮到用戶的習慣和需求,以及頁面的回應時間和效能問題。我們希望本文能夠提供大家一些參考和協助。

以上是如何使用javascript寫一個省市選擇器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn