寫在前頭

前端接案 re-spec,最近再開,「JavaScript 作品實戰直播班」也開始在解決每週作業,loading 比我想像中重,每天都在克服自己對 JavaScript 新知識的心魔,及害怕自己做不出來的恐懼,算是過著十分充實的生活,只能一直告訴自己,撐過去就是我的了!所以文還是要寫,把記憶體釋放一些(笑,接下來就進入本篇的內容了,Let's Go!(?

本篇記錄,會講到如何做出縣市及鄉鎮區連動的選單,還有定位至該鄉鎮區

讓縣市選單運作

連動選單比想像中難實作,參考了不少人的作品,才總算寫出來,先看看完整的程式碼:

const countySelector = document.querySelector('.countyList');
function addCountyList(){
    let allCounty = [];
    let countyStr='';
    countyStr += '<option>請選擇縣市</option>'
    for(let i=0;i<data.length;i++){
        const countyName = data[i].properties.county;
        if(allCounty.indexOf(countyName) == -1 && countyName !== ''){
        allCounty.push(countyName);
        countyStr += `<option value="${countyName}">${countyName}</option>`
        }
    }
    countySelector.innerHTML = countyStr;
}
countySelector.addEventListener('change', addTownList);

const townSelector = document.querySelector('.townList');
townSelector.innerHTML = `<option value="">請選擇鄉鎮區</option>`;

function addTownList(e){
    let countyValue = e.target.value;
    let townStr = `<option value="">請選擇鄉鎮區</option>`;
    let allTown = [];
    let newTownList = '';
    for (let i = 0; i < data.length; i++) {
        let countyMatch = data[i].properties.county;
        if (countyValue == countyMatch) {
            allTown.push(data[i].properties.town);
        }
    }

    newTownList = new Set(allTown);
    newTownList = Array.from(newTownList);
    for (let i = 0; i < newTownList.length; i++) {
        townStr += `<option value="${newTownList[i]}">${newTownList[i]}</option>`
    }

    townSelector.innerHTML = townStr;
    townSelector.addEventListener('change', geoTownView);

}

接下來分段來看,以下是 HTML 的部分:

<div class="areaList">
    <select name="" id="" class="countyList">
    </select>
    <select name="" id="" class="townList">
    </select>
</div>

在 HTML 裡我們定義了兩個 select,分別代表縣市及鄉鎮選單,接下來看到 JavaScript 的部分:

// 先宣告變數來選取代表縣市的 select
const countySelector = document.querySelector('.countyList');
// 使用函式來把縣市的資料取出來
function addCountyList(){
    let allCounty = [];
    let countyStr='';
    countyStr += '<option>請選擇縣市</option>'
    for(let i=0;i<data.length;i++){
        // 取出 data 資料裡的縣市名稱
        const countyName = data[i].properties.county;
        // 這段的意思是,如果在 allCounty 這個陣列裡找不到 countyName,且 countyName 不為空字串,就把 countyName 放進 allCounty 這個陣列裡
        if(allCounty.indexOf(countyName) == -1 && countyName !== ''){
        allCounty.push(countyName);
        // 把縣市名字串累加
        countyStr += `<option value="${countyName}">${countyName}</option>`
        }
    }
    // 並把縣市名字串累加的結果用 innerHTML 放進 countySelector 裡
    countySelector.innerHTML = countyStr;
}
// 對 countySelector 進行監聽,當 countySelector change 時,執行 addTownList 函式
countySelector.addEventListener('change', addTownList);

我們就可以看到縣市的選單了。

讓縣市、鄉鎮區選單連動

接下來我們來實作鄉鎮區名的部分,看到 JavaScript 的部分:

// 一樣先宣告變數來選取代表鄉鎮區的 select
const townSelector = document.querySelector('.townList');
townSelector.innerHTML = `<option value="">請選擇鄉鎮區</option>`;
// 使用函式並帶入參數 e 來取得鄉鎮區的名字
function addTownList(e){
    // 先取得縣市 select 中的 vallue,也就是縣市的名稱
    let countyValue = e.target.value;
    let townStr = `<option value="">請選擇鄉鎮區</option>`;
    let allTown = [];
    let newTownList = '';
    // 然後用迴圈來取得符合條件的鄉鎮區名
    for (let i = 0; i < data.length; i++) {
        //先宣告 countyMatch 為 data 資料中的縣市名
        let countyMatch = data[i].properties.county;
        //用 if 來判斷,如果縣市 select 的值跟 data 資料裡的縣市名相同,就把所有的鄉鎮區名 push 到 allTown 這個陣列裡
        if (countyValue == countyMatch) {
            allTown.push(data[i].properties.town);
        }
    }
    // 然後使用 Set 方法來產生一個集合讓陣列元素不會重複
    newTownList = new Set(allTown);
    // 再從剛才的集合產生陣列
    newTownList = Array.from(newTownList);
    for (let i = 0; i < newTownList.length; i++) {
        // 把鄉鎮區名累加成字串
        townStr += `<option value="${newTownList[i]}">${newTownList[i]}</option>`
    }
    // 並把鄉鎮區名字串累加的結果用 innerHTML 放進 townSelector 裡
    townSelector.innerHTML = townStr;
    // 對 townSelector 進行監聽,當 townSelector change 時,執行 geoTownView 函式
    townSelector.addEventListener('change', geoTownView);
}

此時縣市及鄉鎮區的選單就可以連動了!未選取縣市時,無法顯示鄉鎮區,選取了縣市,才能接著選鄉鎮區。

選取縣市及鄉鎮區後定位至該鄉鎮區

現在我們要實作選取縣市及鄉鎮區,地圖會定位至該鄉鎮區,JavaScript 的部分如下:

function geoTownView(e) {
    // 先取得鄉鎮區 select 中的 vallue,也就是鄉鎮區的名稱
    let town = e.target.value;
    let townLatLng = [];
    let county = '';

    for (let i = 0; i < data.length; i++) {
        // 宣告變數取得 data 裡的鄉鎮區、縣市名稱及其經緯度
        let townTarget = data[i].properties.town;
        let countyTarget = data[i].properties.county;
        let lat = data[i].geometry.coordinates[0];
        let lng = data[i].geometry.coordinates[1];
        // 比較鄉鎮區名及縣市名,如果兩者皆符合,則取得鄉鎮區的經緯度
        if (townTarget == town && countyTarget == countySelector.value) {
            // 並把經緯度賦值到變數 townLatLng
            townLatLng = [lng, lat];
            // 宣告變數 county 等於 data 裡的縣市資料
            county = data[i].properties.county;
        }
    }
    // 把鄉鎮經緯度代入,並設定 zoom 值為 17(此可依需求調整)
    map.setView(townLatLng, 17);
    // 把上面宣告的 town 及 county 變數帶入 renderList() 函式中
    renderList(town,county);
}
// 此函式為下篇內容,我們下次再聊
function renderList(town,county){}

這一段寫完,我們只要選好縣市及鄉鎮區,就會飛到該鄉鎮區了~

最後我們來簡單的美化 select

我們在 CSS 加上下面這段,select 就美觀多了~

.areaList{
    display:flex;
    justify-content: center;
    flex-wrap: wrap;
}

.countyList, .townList{
    width:80%;
    height: 30px;
    border-radius: 5px;
    border:1.3px solid #072e00;
}

.countyList{
    margin-bottom:10px;
}

.countyList option{
    text-align: center;
}

本週打完收工!我們下次見~

資料補充


##口罩地圖 #六角學院 #台灣口罩地圖-2020 防疫要贏 #javascript #css #JavaScript 入門篇 - 學徒的試煉 #口罩地圖 #六角學院 #台灣口罩地圖-2020 防疫要贏 #javascript #css #JavaScript 入門篇 - 學徒的試煉







Related Posts

如何在 Windows 安裝 OpenPose 跟使用 Python API 來偵測人體姿態

如何在 Windows 安裝 OpenPose 跟使用 Python API 來偵測人體姿態

自駕車 Sensor Fusion in Visual Perception 簡介

自駕車 Sensor Fusion in Visual Perception 簡介

[13] 值 - 字串

[13] 值 - 字串


Comments