初試啼聲,只用原生 JS 跟 CSS 寫「口罩地圖 」Ep.02


Posted by ABow_Chen on 2020-06-14

寫在前頭

由於目前的狀況是斜槓斜槓再斜槓,正職之外,前端接案、學習、每日解六角學院的 JS 任務及下週即將開始的 JS 直播班課程,真的有點分身乏術…寫技術文比想像中花更多時間,在寫的同時,等同又做了一次口罩地圖,所以接下來幾篇會朝比較輕量的方向寫文,讓自己的時間管理更彈性!但也希望不要分太多篇囉~

本篇記錄,會講到在 marker 的 bindPopup() 裡面塞進口罩數量及相對應的顏色判斷

為藥局 marker 的 Popup 塞進更完整的資訊

稍微回顧一下,上次我們只做到在 Popup 裡塞進藥局名稱:

markers.addLayer(L.marker([lat,lng], {icon: mask}).bindPopup(`<h3>${pharmacyName}</h3>`));

呈現的結果如下圖:

現在我們要來新增更完整的藥局資訊,包含地址、電話、備註及成人口罩及兒童口罩的數量,所以我們先在以下這段添加新的變數:

 // 此為截取局部的程式碼,主要是讓讀者更清楚前後關係
function addMarker(){
    for(let i = 0;i<data.length;i++){
        const pharmacyName = data[i].properties.name;
// 上次已經有的成人及兒童口罩數量,用在 marker 的顏色判斷上,這次會在用於 Popup 資料的顏色判斷 
        const maskAdult = data[i].properties.mask_adult;
        const maskChild = data[i].properties.mask_child;
        const lat = data[i].geometry.coordinates[1];
        const lng = data[i].geometry.coordinates[0];
// 新增三個新的變數,分別是地址、電話及備註        
        const pharmacyAddress = data[i].properties.address;
        const pharmacyPhone = data[i].properties.phone;
        const pharmacyNote = data[i].properties.note;

接下來,我們要把原本 bindPopup() 的內容改成如下:

// 運用 ES6 語法來寫 HTML 變得十分直覺
markers.addLayer(L.marker([lat,lng], {icon: mask}).bindPopup(
`<div class="popupInfo">
    //這裡就運用了上面那一段的變數,用  ES6 語法塞進 HTML 中
    <p class="popupTitle" data-name="${pharmacyName}"><span>${pharmacyName}</span></p>
    <hr>
    // 這裡有引入 fontawsome,所以你如果有使用 fontawsome 的需求,別忘了在 HTML 引入,細節就不再贅述
    <p class="popupText"><i class="fas fa-map-marker-alt"></i> ${pharmacyAddress}</p>
    <p class="popupText"><i class="fas fa-phone-square-alt"></i> ${pharmacyPhone}</p>
    <p class="popupNote"> ${pharmacyNote}</p>
    <div class="panelMaskNum" data-name="${pharmacyName}">
        <div class="${maskAdultJudge}">
            <div class="popupLayout">
            <img class="adultIconS" src="" alt="">
            <p class="popupMaskNum">${maskAdult}</p>
            </div>
        </div>
        &nbsp;<div class="${maskChildJudge}">
            <div class="popupLayout">
            <img class="kidIconS" src="" alt="">
            <p class="popupMaskNum">${maskChild}</p>
            </div>
        </div>
    </div>
</div>`
));

這一段多了不少 CSS 樣式的設定,但結構挺單純的。

為口罩數量資訊加上判斷

接下來,我們在 Popup 裡面的成人及兒童口罩,要根據不同的數量判斷,給出不同的背景色,來提醒消費者。

首先,我們在原本 marker 顏色判斷的程式碼下方增加這些內容:

let maskAdultJudge;
let maskChildJudge;

if (maskAdult >= 100) {
// 若數量符合條件,就給出相對應的背景色
    maskAdultJudge = 'bg-sufficient';
        } else if (maskAdult < 100 && maskAdult !== 0) {
            maskAdultJudge = 'bg-insufficient';
        } else {
            maskAdultJudge = 'bg-none';
        }
        if (maskChild >= 100) {
            maskChildJudge = 'bg-sufficient';
        } else if (maskChild < 100 && maskChild !== 0) {
            maskChildJudge = 'bg-insufficient';

        } else {
            maskChildJudge = 'bg-none';
        }

所以綜合前面的內容,完整的程式碼如下:

function addMarker(){
    for(let i = 0;i<data.length;i++){
        const pharmacyName = data[i].properties.name;
        const maskAdult = data[i].properties.mask_adult;
        const maskChild = data[i].properties.mask_child;
        const lat = data[i].geometry.coordinates[1];
        const lng = data[i].geometry.coordinates[0];
        const pharmacyAddress = data[i].properties.address;
        const pharmacyPhone = data[i].properties.phone;
        const pharmacyNote = data[i].properties.note;
        if(maskAdult == 0 || maskChild == 0){
            mask = redIcon;
        }else if (maskAdult < 100 && maskAdult !== 0 || maskChild < 100 && maskChild !== 0){
            mask = orangeIcon;
        }else{
            mask = greenIcon;
        }
        let maskAdultJudge;
        let maskChildJudge;

        if (maskAdult >= 100) {
            maskAdultJudge = 'bg-sufficient';
        } else if (maskAdult < 100 && maskAdult !== 0) {
            maskAdultJudge = 'bg-insufficient';
        } else {
            maskAdultJudge = 'bg-none';
        }
        if (maskChild >= 100) {
            maskChildJudge = 'bg-sufficient';
        } else if (maskChild < 100 && maskChild !== 0) {
            maskChildJudge = 'bg-insufficient';

        } else {
            maskChildJudge = 'bg-none';
        }
        L.marker([lat,lng], {icon: mask}).addTo(map);
        markers.addLayer(L.marker([lat,lng], {icon: mask}).bindPopup(
        `<div class="popupInfo">
            <p class="popupTitle" data-name="${pharmacyName}"><span>${pharmacyName}</span></p>
            <hr>
            <p class="popupText"><i class="fas fa-map-marker-alt"></i> ${pharmacyAddress}</p>
            <p class="popupText"><i class="fas fa-phone-square-alt"></i> ${pharmacyPhone}</p>
            <p class="popupNote"> ${pharmacyNote}</p>
            <div class="panelMaskNum" data-name="${pharmacyName}">
                <div class="${maskAdultJudge}">
                    <div class="popupLayout">
                    <img class="adultIconS" src="" alt="">
                    <p class="popupMaskNum">${maskAdult}</p>
                    </div>
                </div>
                &nbsp;<div class="${maskChildJudge}">
                    <div class="popupLayout">
                    <img class="kidIconS" src="" alt="">
                    <p class="popupMaskNum">${maskChild}</p>
                    </div>
                </div>
            </div>
        </div>`
        ));
    }
    map.addLayer(markers);
}

再來是 CSS 的設定,效果十分單純,裡面運用了 Flex 來排版,新增程式碼如下:

/* Popup 內資訊的樣式設定 */

.panelMaskNum{
    padding: 20px 0 10px 0; 
    font-size: 20px;
    display:flex;
    justify-content: center;
}

.infoLayout{
    display: flex;
    justify-content: center;
    align-items: center;
}

.popupInfo p{
    margin:0 !important;
}

.popupLayout{
    display: flex;
    justify-content: center;
    align-items: center;
    }
.popupInfo hr{
    border:0.5px solid #072e00;
}

.popupTitle{
    font-size: 20px;
    font-weight: 900;
    color:#072e00;
}

.popupTitle span{
    padding-left: 5px;
}

.popupText{
    color: #072e00;
    padding-top: 5px;
    font-size: 15px;
}

.popupNote{
    padding-top: 5px;
    font-size: 10px;
    color: rgb(125, 125, 125);
}

.popupMaskNum{
    margin:0 !important;
}

.pop-style{
    font-size: 1.3em;
}

.popupBtn{
    display:flex;
    justify-content:flex-end;
}

/* 數量判斷後,相對應的背景顏色 */

.bg-sufficient{
    color:white;
    background-color: #63cf9c;
    padding: 10px;
    border-radius: 50px;
    display: inline-block;
    width: 130px;
    text-align: center;
    margin-bottom:5px;
    text-shadow: 1px 1px 4px rgba(0, 0, 0,0.6);
}

.bg-insufficient{
    color:white;
    background-color: #FAB3A9;
    padding: 10px;
    border-radius: 50px;
    display: inline-block;
    width: 130px;
    text-align: center;
    margin-bottom:5px;
    text-shadow: 1px 1px 4px rgba(0, 0, 0,0.6);
}

.bg-none{
    color:white;
    background-color: #B4BDC1;
    padding: 10px;
    border-radius: 50px;
    display: inline-block;
    width: 130px;
    text-align: center;
    margin-bottom:5px;
    text-shadow: 1px 1px 4px rgba(0, 0, 0,0.6);
}

到這邊,我們就完成了在 Popup() 裡面塞進口罩數量及相對應的顏色判斷以及每間藥局的資訊了。


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







Related Posts

終端機顯示Cannot find module 'sass'

終端機顯示Cannot find module 'sass'

ASP.NET Core Web API 入門教學 - DbContext取得資料庫資料時注意事項

ASP.NET Core Web API 入門教學 - DbContext取得資料庫資料時注意事項

部署 (1) —— 建立 AWS EC2 主機及 SSH 連線

部署 (1) —— 建立 AWS EC2 主機及 SSH 連線


Comments