今天是 2022 年最後一個上班日, 單位裡有兩位老同事 65 歲屆齡退休, 看到人家明年就可以睡到自然醒, 令我好生羨慕. 我要到 2031 年 6 月 30 才退, 還有 8 年半左右, 我到 GitHub 個人網站查看上回寫的退休倒數計日程式, 精確來說是 8 年又 183 天, 參考 :
# 退休倒數計時器
其實還有很多倒數計日的應用時機, 例如會考, 學測, ... 甚至是預期的平均壽命都可以. 因為很久沒寫 jQueryUI 了, 一時技癢就拿這個來練習一下吧! 將我的退休倒時記日器一般化, 可以選定截止日期, 計算離那個日期還有幾年幾天.
最直覺的方式是用下拉式選單 SelectMenu, 年月日都設一個, 然後監聽 onchange 事件, 任何一個選擇器改變就立即進行倒數計算. 關於 SelectMenu 用法參考 :
如下面範例 1 所示 :
<!doctype html>
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="https://code.jquery.com/ui/1.12.1/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"></script>
<style>
body {
font-family: 微軟正黑體, Arial, Helvetica, sans-serif;
font-size:12px;
}
</style>
</head>
<body>
<div style="padding: 2px; margin: 3px;">
<h3>倒數日數計算</h3>
<p><b>請選擇截止日期 :</b></p>
<select id="year">
<option value="2023">2023 年</option>
<option value="2024">2024 年</option>
<option value="2025">2025 年</option>
<option value="2026">2026 年</option>
<option value="2027">2027 年</option>
<option value="2028">2028 年</option>
<option value="2029">2029 年</option>
<option value="2030">2030 年</option>
<option value="2031">2031 年</option>
<option value="2032">2032 年</option>
<option value="2033">2033 年</option>
<option value="2034">2034 年</option>
<option value="2035">2035 年</option>
<option value="2036">2036 年</option>
<option value="2037">2037 年</option>
<option value="2038">2038 年</option>
<option value="2039">2039 年</option>
<option value="2040">2040 年</option>
<option value="2041">2041 年</option>
<option value="2042">2042 年</option>
<option value="2043">2043 年</option>
<option value="2044">2044 年</option>
<option value="2045">2045 年</option>
<option value="2046">2046 年</option>
<option value="2047">2047 年</option>
<option value="2048">2048 年</option>
<option value="2049">2049 年</option>
<option value="2050">2050 年</option>
</select>
<select id="month">
<option value="Jan">1 月</option>
<option value="Feb">2 月</option>
<option value="Mar">3 月</option>
<option value="Apr">4 月</option>
<option value="May">5 月</option>
<option value="Jun">6 月</option>
<option value="Jul">7 月</option>
<option value="Aug">8 月</option>
<option value="Sep">9 月</option>
<option value="Oct">10 月</option>
<option value="Nov">11 月</option>
<option value="Dec">12 月</option>
</select>
<select id="date">
<option value="1">1 日</option>
<option value="2">2 日</option>
<option value="3">3 日</option>
<option value="4">4 日</option>
<option value="5">5 日</option>
<option value="6">6 日</option>
<option value="7">7 日</option>
<option value="8">8 日</option>
<option value="9">9 日</option>
<option value="10">10 日</option>
<option value="11">11 日</option>
<option value="12">12 日</option>
<option value="13">13 日</option>
<option value="14">14 日</option>
<option value="15">15 日</option>
<option value="16">16 日</option>
<option value="17">17 日</option>
<option value="18">18 日</option>
<option value="19">19 日</option>
<option value="20">20 日</option>
<option value="21">21 日</option>
<option value="22">22 日</option>
<option value="23">23 日</option>
<option value="24">24 日</option>
<option value="25">25 日</option>
<option value="26">26 日</option>
<option value="27">27 日</option>
<option value="28">28 日</option>
<option value="29">29 日</option>
<option value="30">30 日</option>
<option value="31">31 日</option>
</select>
</div>
<div class="ui-state-highlight ui-corner-all" style="padding: 5px; margin: 5px; width:290px;">
<span class="ui-icon ui-icon-info"></span>
<span id="msg" style="font-weight: bold; "></span>
</div>
<input type='hidden' id='year_val' value='2023'>
<input type='hidden' id='month_val' value='1'>
<input type='hidden' id='date_val' value='1'>
<script>
$(function(){
function calculate(){
var the_end=$("#month_val").val() + ' ' +
$("#date_val").val() + ', ' +
$("#year_val").val();
var t=Date.parse(the_end)-new Date().getTime();
var total_days=Math.floor(t / (1000 * 60 * 60 * 24));
var years=Math.floor(total_days / 365);
var days=total_days % 365;
var msg="離截止日期還有 " + years + " 年 " + days + " 天 (共 " +
total_days + " 天)";
$("#msg").text(msg);
}
$("#year").selectmenu({width: 120});
$("#month").selectmenu({width: 80});
$("#date").selectmenu({width: 90});
$('#year').on('selectmenuchange', function() {
$("#year_val").val($(this).val());
calculate();
});
$('#month').on('selectmenuchange', function() {
$("#month_val").val($(this).val());
calculate();
});
$('#date').on('selectmenuchange', function() {
$("#date_val").val($(this).val());
calculate();
});
calculate(); //初次仔入網頁時顯示初始值
});
</script>
</body>
</html>
此例網頁中設置了三個隱藏元件 (type=hidden 的 input 元素), 分別用來儲存三個 SelectMenu 元件所選定之值, 每一個下拉式選單都有綁定 onchange 事件, 只要選項被改變就會更新相對應之隱藏元件之值, 這部分邏輯被寫成 calculate() 函式來處理. 下拉式選單的初始值就是第一個選項 (2023-01-01) 之值. 注意, SelectMenu 元件的寬度無法用 style 屬性設定 (無效), 必須在初始化時傳入 {width: } 物件來設定. 結果如下 :
哈哈, 這正是我的退休倒數日數.
下面改用 HTML5 的 Date 表單元件來選取截止日期, 用法參考下面這篇的範例 4 :
Date 元件可綁定 onchange 事件, 以便選定日期後觸發事件處理函式, 參考 :
測試 2 : 用 HTML5 的 Date 元件作為日期選擇器以計算倒數日數 [看原始碼]
<!doctype html>
<html>
<head>
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="https://code.jquery.com/ui/1.12.1/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"></script>
<script>
function calculate(e){
alert(e.target.value);
}
</script>
<style>
body {
font-family: 微軟正黑體, Arial, Helvetica, sans-serif;
font-size:12px;
}
</style>
</head>
<body>
<div style="padding: 2px; margin: 3px;">
<h3>倒數日數計算</h3>
<p><b>請選擇截止日期 :</b></p>
<input type="date" id="date" onchange="handler(event)">
</div>
<div class="ui-state-highlight ui-corner-all" style="padding: 5px; margin: 5px; width:290px;">
<span class="ui-icon ui-icon-info"></span>
<span id="msg" style="font-weight: bold; "></span>
</div>
<script>
function handler(event){
var YMD=event.target.value.split("-"); // [2022,12,31]
var month=['Jan', 'Feb', 'Apr', 'Mar', 'May', 'Jun', 'Jul', 'Aug',
'Sep','Oct', 'Nov', 'Dec'];
var the_end=month[parseInt(YMD[1])-1] + ' ' + YMD[2] + ', ' + YMD[0];
var t=Date.parse(the_end)-new Date().getTime();
var total_days=Math.floor(t / (1000 * 60 * 60 * 24));
var years=Math.floor(total_days / 365);
var days=total_days % 365;
var msg="離截止日期還有 " + years + " 年 " + days + " 天 (共 " +
total_days + " 天)";
$("#msg").text(msg);
}
</script>
</body>
</html>
此例使用 HTML5 表單元件中的日期選擇器 (type=date 的 input 元件) 來選取截止日期, 注意, 此處所綁定的 onchange 事件, 呼叫端之傳入參數名稱一定要用 event, 亦即必須用 onchange="handler(event)", 用其他參數名稱會出現錯誤 (函式端則不受限, 可用 event 或 e 等等). 由於 Date 元件預設的日期格式為 YYYY-MM-DD, 所以要用 split() 將 Y, M, D 拆開, 其中 M 用陣列對照轉換成英文簡寫, 再與 Y, D 組成例如 'Dec 31, 2022' 的日期格式字串, 結果如下 :
因為過了 12 點, 所以比上面範例 1 少一天啦.
有空可以用 jQueryUI 本身的 datepicker 來做, 參考 :
沒有留言 :
張貼留言