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


Posted by ABow_Chen on 2020-06-21

寫在前頭

保守估計再二至三篇,就可以結束這個系列文,六角學院的「JavaScript 作品實戰直播班」也開始了,身為學員的我,頓時又爆忙了起來,總之,文章能寫多少就盡力寫,但主線任務還是放在「JavaScript 作品實戰直播班」上囉!不過廢話不多說,今天的文章開始囉~

本篇記錄,會講到在左側 panel 裡的日期判斷及可購買日期的提醒

為地圖左側加入一個 panel

地圖的基本功能已完成,現在我們要來提升使用者體驗,要在地圖左側加入一個 panel 就是第一步,所以我們先在 HTML 建構出 panel 的區塊:

<div class="panel">
    // panel 的上半部
    <div class="panelTop">
    // info 區塊會用來判斷今天日期
        <div class="info">
            <div class="infoDate">
                <div class="todayDate"><h2>今天是&nbsp;<span></span></h2></div>
            </div>
            <div class="infoWeek">
                <h2>&nbsp;星期<span></span> </h2>
            </div>
        </div>
        // 此區塊則會告知購買資訊及下次可購買的日期
        <div class="idBuyText">
        <p class="idNumAll">身分證末碼數字&nbsp;<span>不限</span>&nbsp;皆可購買</p>
        </div>
        <div class="nextBuyDateText">
            <p class="nextBuyDate">今日購買,下次可購買日期為&nbsp;<span class="nextBuyDateNum"></span>&nbsp;星期<span class="nextBuyDay"></span></p>
        </div>
        // panel 裡有一個區塊是用來選擇縣市及鄉鎮的也先預留起來
        <div class="areaList">
            <select name="" id="" class="countyList">
            </select>
            <select name="" id="" class="townList">
            </select>
        </div>
    </div>
    // 這區塊是 panel 的下半部,這裡要塞進藥局的列表
    <div class="pharmacyList">
    </div>
</div>

接著我們要設定 CSS 的部分:

//定義出電腦版畫面裡 panel 的佔比,並讓 panel 固定在畫面的左邊,則帶有點陰影
.panel{
    width: 25%;
    height: 100%;
    position:absolute;
    top: 0;
    left:0;
    z-index: 99999;
    background-color:white;
    box-shadow: 2px 0px 3px 1px rgba(0, 0, 0, 0.25);
}

.panelTop{
    height: 50%;
    background-color:#63cf9c ;
    position: relative;
    display:flex;
    flex-direction: column;
    justify-content: center;
    margin-top:-2%;
    box-shadow: 0px 2px 3px 1px rgba(0, 0, 0, 0.3);
}

此時畫面呈現會如下:

在 panel 上半部塞進日期資訊

panel 的空間已經建構好了,接下來我們要在上半部塞進日期判斷的資訊,接下來是 JavaScript 的工作了。

function renderDate(){
    const dateInfo = new Date();
    const day = dateInfo.getDay();
    let date = dateInfo.getDate();
    let month = dateInfo.getMonth()+1;
    let year = dateInfo.getFullYear();
    const dayChinese = judgeChineseDay(day);
    const twoWeeks = 1000 * 60 * 60 * 24 * 14;
    const twoWeeksDate = new Date(new Date().getTime() + twoWeeks);
    let nextBuyTimeDate = twoWeeksDate.getDate();
    let nextBuyTimeMonth = twoWeeksDate.getMonth() + 1;
    let nextBuyTimeYear = twoWeeksDate.getFullYear();
    let today;
    let nextBuyDate;
    if(month.toString().length == 1){
        month = '0' + month;
        }
    if(date.toString().length == 1){
        date = '0' + date;
        }
    today = year + '-' + month + '-' + date;

    if (nextBuyTimeMonth.toString().length == 1) {
        nextBuyTimeMonth = '0' + nextBuyTimeMonth;
    }
    if (nextBuyTimeDate.toString().length == 1) {
        nextBuyTimeDate = '0' + nextBuyTimeDate;
    }
    nextBuyDate = nextBuyTimeYear + '-' + nextBuyTimeMonth + '-' + nextBuyTimeDate;
    if(day == 1 || day == 3 || day == 5){
        document.querySelector('.idNumAll').style.display = 'block';
    }else if(day == 2 || day == 4 || day == 6){
        document.querySelector('.idNumAll').style.display = 'block';
    }
    else if(day == 0){
        document.querySelector('.idNumAll').style.display = 'block';
    }else{
        alert('沒有這一天');
    }
        document.querySelector('.todayDate h2 span').textContent = today;
        document.querySelector('.infoWeek h2 span').textContent = dayChinese;
        document.querySelector('.nextBuyDate span').textContent = nextBuyDate;
        document.querySelector('.nextBuyDay').textContent = dayChinese;
    }

這裡有點長,我們分段來看:

// 先寫一個函式,把日期給渲染出來
function renderDate(){
    //這裡是取得日期的方法,MDN 上就有相關說明,附上網址在最下方資料參考處,若有需要可以參考
    const dateInfo = new Date();
    const day = dateInfo.getDay();
    let date = dateInfo.getDate();
    //因為月份是 0 到 11 所以我們要 +1
    let month = dateInfo.getMonth()+1;
    let year = dateInfo.getFullYear();
    // 下面這一段是我們要判斷星期的數字,並套進函式裡轉換成中文字
    const dayChinese = judgeChineseDay(day);
    // 這段是我們要計算出今日購買後,隔兩個禮拜後的可購買日,而以下的算式就是將毫秒計算成天數,總和就是 14 天
    const twoWeeks = 1000 * 60 * 60 * 24 * 14;
    // 然後把今天加了 14 天後的日期賦予到一個變數上
    const twoWeeksDate = new Date(new Date().getTime() + twoWeeks);
    let nextBuyTimeDate = twoWeeksDate.getDate();
    let nextBuyTimeMonth = twoWeeksDate.getMonth() + 1;
    let nextBuyTimeYear = twoWeeksDate.getFullYear();
    let today;
    let nextBuyDate;
}

接下來來看這一段:

// 把月份轉成字串,如果長度只有 1,那就在前面加上 0,針對 1 月至 9月
if(month.toString().length == 1){
    month = '0' + month;
    }
// 把日期轉成字串,如果長度只有 1,那就在前面加上 0,針對 1 日至 9日
if(date.toString().length == 1){
    date = '0' + date;
    }
//然後把今天的日期組出來    
today = year + '-' + month + '-' + date;
//用同樣的邏輯來判斷 14 天後的下次購買日的日期
if (nextBuyTimeMonth.toString().length == 1) {
    nextBuyTimeMonth = '0' + nextBuyTimeMonth;
}
if (nextBuyTimeDate.toString().length == 1) {
    nextBuyTimeDate = '0' + nextBuyTimeDate;
}
//然後把 14 天後的日期組出來    
nextBuyDate = nextBuyTimeYear + '-' + nextBuyTimeMonth + '-' + nextBuyTimeDate;

最後一段如下:

//此段的寫法原本是為了判斷星期幾對應身分證字號末碼而寫的,但後來規則改了,所以不管星期幾,顯示的資訊都是 .idNumAll 裡的「身分證末碼數字 不限 皆可購買」,所以這段僅供參考,純粹是規則改變,我以更動最少的方式為考量而寫的
if(day == 1 || day == 3 || day == 5){
    document.querySelector('.idNumAll').style.display = 'block';
}else if(day == 2 || day == 4 || day == 6){
    document.querySelector('.idNumAll').style.display = 'block';
}
// 這裡需要注意的是,星期日的 day 是 0,而不是 7
else if(day == 0){
    document.querySelector('.idNumAll').style.display = 'block';
}else{
    alert('沒有這一天');
}
    //最後在 HTML 相對應的標籤裡,把資訊渲染出來
    document.querySelector('.todayDate h2 span').textContent = today;
    document.querySelector('.infoWeek h2 span').textContent = dayChinese;
    document.querySelector('.nextBuyDate span').textContent = nextBuyDate;
    document.querySelector('.nextBuyDay').textContent = dayChinese;
}

加入 init() 裡

接著我們把 renderDate() 加入 init() 裡,讓網頁載入時預設執行。

// 原本只有 getData(),現在再加入 renderDate()
function init(){
    renderDate();
    getData();
}

將星期的數字轉換成中文字

我們習慣把星期寫成中文字,尤其星期日如果講成星期 7 會非常奇怪,所以我們就需要有個轉換的功能,因此我們寫了一個函式如下:

// 這個函式的功能很單純,就是把帶入的 day 從數字轉換成中文字
function judgeChineseDay(day){
    switch(day){
        case 1:
            return '一';
            break;
        case 2:
            return '二';
            break;
        case 3:
            return '三';
            break;
        case 4:
            return '四';
            break;
        case 5:
            return '五';
            break;
        case 6:
            return '六';
            break;
        case 0:
            return '日';
            break;
    }

}

以上這些部分完成後,我們就可以在 panel 看到今天的日期及 14 天後可購買的日期了!

資料補充


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







Related Posts

DAY21:Highest Scoring Word

DAY21:Highest Scoring Word

Show Me the DAG - An Introduction to Causal Graphs

Show Me the DAG - An Introduction to Causal Graphs

跟著 GitHub Learning Lab 實作一波

跟著 GitHub Learning Lab 實作一波


Comments