RWD實作(2)
一個RWD的BMI計算機
檔案:index.html、index.css、index.js、bk.png
學習重點:
網頁的ID與class應用。
CSS的display屬性。
Javascript的事件與傾聽器。
Javascript方法與變數。
完整程式碼
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>BMI計算機</title>
<!-- Google 網路字型https://fonts.google.com -->
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="main.css" />
<script type="text/javascript" src="main.js"></script>
</head>
<body>
<header>
<h1 id="title">BMI計算機</h1>
</header>
<section id="home">
<!-- 接收使用者輸入的地方 -->
<h2>輸入基本資料</h2>
<section class="input_bk">
<h3 class="title">日期</h3>
<input type="text" id="txtDate" />
</section>
<section class="input_bk">
<h3 class="title">身高(公分)</h3>
<input type="number" id="txtHeight" placeholder="請輸入身高"/>
</section>
<section class="input_bk">
<h3 class="title">體重(公斤)</h3>
<input type="number" id="txtWeight" placeholder="請輸入體重" />
</section>
<button id="btnCalculate">計算</button>
<button id="btnClear">重設欄位</button>
</section>
<section id="result">
<!-- 顯示計算結果的地方 -->
<h2>計算日期</h2>
<p id="result_date" class="input_bk"> </p>
<h2>基本資料</h2>
<p id="result_info" class="input_bk"> </p>
<h2>BMI</h2>
<p id="result_bmi" class="input_bk"> </p>
<h2>評語</h2>
<p id="result_suggest" class="input_bk"> </p>
<button id="btnBack">回上頁</button>
</section>
</body>
</html>
main.css
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body
{
font-family: '微軟正黑體', 'LiHei Pro', sans-serif; /* 設定字型 */
background-image: url(bk.png); /* 設定背景圖 */
}
h1
{
color: white; /* 設定文字顏色 */
padding: 6px; /* 設定內邊距 */
font-size: 1.5em; /* 設定文字大小,em為相對大小 */
font-weight: bold; /* 設定粗體字,bold=粗體、normal=一般 */
text-align: center; /* 文字置中顯示 */
/* 漸層效果,0%~100%, 由左至右的填色範圍 */
background-image: linear-gradient(to right, rgba(241,231,103,1) 0%, rgba(254,182,69,1) 100%);
}
h2
{
margin: 4px 0 4px 14px; /* 上、右、下、左 */
padding: 3px;
color: #7189A4;
font-size: 1.1em;
font-weight: normal;
text-shadow: 2px 2px 4px white; /* 設定文字陰影,參數依序為:X、Y、模糊、顏色 */
}
h3
{
font-size: 1.1em;
float: left; /* 將元素浮動到左邊 */
width: 30%; /* 設定元素寬度 */
line-height: 1.4em; /* 設定行高 */
vertical-align: middle; /* 垂直置中(需搭配line-height設定才有效 */
}
input
{
font-size: 1.5em;
width: 50%;
border: 1px solid #777777; /* 設定元素邊框,參數依序為:厚度 樣式 顏色 */
}
button
{
font-size: 1.5em;
margin: 2px 1% 2px 1%; /* 設定元素外邊距 */
padding: 4px;
width: 98%;
border-radius: 10px; /* 設定元素四個角為圓角 */
border: 1px solid orange;
background: linear-gradient(to bottom, rgba(252,234,187,1) 0%,
rgba(252,205,77,1) 50%,
rgba(248,181,0,1) 51%,
rgba(251,223,147,1) 100%);
}
.input_bk
{
background-color: white;
color: black;
padding: 6px;
margin: 0px 6px 12px 6px;
border-radius: 6px;
}
/* 初始化哪一個頁面要先顯示 */
#home {display: block;} /* 將id=home元素設定為block顯示模式 */
#result {display: none;} /* 將id=result元素設定為不顯示 */
/*
平板樣式:解析度840px以上(含840px)
*/
@media only screen and (min-width: 840px)
{
#home
{
display: block;
float: left;
width: 50%;
box-sizing: border-box; /* 設定元素寬度的計算包含邊框 */
}
#result
{
display: block;
float: right;
width: 50%;
box-sizing: border-box;
}
#btnBack
{
display: none;
}
}
關於CSS Reset
雖然HTML、CSS是由W3C定義好的標準,但是各大瀏覽器(如:Chrome、IE、Edge、Firefox等等)為了展現自身的特色和優勢,都會自行加入一些額外的的設定或不同的預設值,造成網頁設計師在排版時,必須針對每個瀏覽器的相異處,付出額外的心力來針對不同的地方來調整或改寫CSS語法。
有時甚至連自家同一個瀏覽器,因為不同版本,也會造成排版上的差異,例如:IE6、IE7、IE8等等。
世界知名CSS大師「Eric A. Meyer」在部落格上曾經發表過一篇關於CSS Reset文章,在這篇文章,他整理出了一個很棒的解決方案「Reset CSS」,針對 CSS語法最容易出問題的部份,例如:margin(外間距)、內間距(padding)等等各大瀏覽器最常發生不一致的地方,將它們全部統一歸0,其他像文字大小、單位、行高等等也全部統成一樣的大小,只要直接掛上這一段「Reset CSS」語法,就可以讓所有的各大瀏覽的設定值變成一樣,呈現出一樣的版面設計。
Eric A. Meyer CSS Reset文章
main.js
//
// 這是我的Javascript庫(這是註解)
//
// 備註:Javascript語法有大小寫區別,請注意
//
// 將document.getElementById呼叫簡化成$
function $(id)
{
return document.getElementById(id);
}
// 設定DOMContentLoaded傾聽器,該傾聽器為網頁載入完成後呼叫
document.addEventListener("DOMContentLoaded", function()
{
// 設定「計算」按鈕被點擊的傾聽器,點擊後會呼叫calculateBmi方法
$("btnCalculate").addEventListener("click", calculateBmi, false);
// 設定「重設」按鈕被點擊的傾聽器,點擊後會呼叫clear方法
$("btnClear").addEventListener("click", clear, false);
// 設定「回上一頁」按鈕被點擊的傾聽器,點擊後會呼叫showHome方法
$("btnBack").addEventListener("click", showHome, false);
// 媒體查詢傾聽器,當畫面大小改變就會被觸發,true=最少有840px, false=低於840px, Javascript media query
window.matchMedia("(min-width: 840px)").addListener(function()
{
if(window.matchMedia("(min-width: 840px)").matches)
{
$("result").style.display = "block"; // 改變CSS樣式,將id=result元素顯示
$("home").style.display = "block"; // 改變CSS樣式,將id=home元素顯示
$("title").innerHTML = "BMI計算機"; // 修改id=title元素內容為「BMI計算機」
}
else
{
$("result").style.display = "none"; // 改變CSS樣式,將id=result元素隱藏
$("home").style.display = "block"; // 改變CSS樣式,將id=home元素顯示
$("title").innerHTML = "BMI計算機"; // 修改id=title元素內容為「BMI計算機」
}
});
// 呼叫clear方法
clear();
// 除錯訊息,僅有在開發工具console視窗才看的到
console.log("我想顯示的東西");
}, false);
// 計算BMI的方法
function calculateBmi()
{
// 取得日期
var date = $("txtDate").value;
// 取出使用者輸入的身高(型態為字串)
var h = $("txtHeight").value;
// 取出使用者輸入的體重(型態為字串)
var w = $("txtWeight").value;
// 將身高字串轉成小數數字
var height = parseFloat(h);
// 將體重字串轉成小數數字
var weight = parseFloat(w);
// 判斷輸入值是否合法, isNan()方法用來判斷是否為數字,「||」為「或者」的意思
if(isNaN(height) || height >= 300 || height <= 20)
{
// 使用alert方法顯示彈出式視窗
lert("不合法的身高值(需介於21公分至299公分之間)");
return;
}
if(isNaN(weight) || weight > 150 || weight < 1)
{
// 使用alert方法顯示彈出式視窗
alert("體重直不合法(需介於2公斤至149公斤之間)");
return;
}
// BMI公式 = 體重 / (身高x身高); PS. 身高單位為公尺
height = height / 100; // 將身高轉換成公尺
var bmi = weight / (height * height);
// 取小數以下兩位就好, round=四捨五入, ceil=無條件進位
bmi = Math.floor(bmi * 100) / 100; // Math.floor為無條件去掉小數
// 判斷BMI結果並給予評語
var suggest = "";
if(bmi < 18.5) suggest = "太瘦";
else if(bmi >= 18.5 && bmi < 24) suggest = "標準";
else if(bmi >= 24 && bmi < 27) suggest = "稍重";
else if(bmi >= 27 && bmi < 30) suggest = "太重";
else if(bmi >= 30 && bmi < 35) suggest = "超級重";
else if(bmi >= 35) suggest = "巨大";
// 將結果顯示到網頁上
$("result_date").innerHTML = date; // 顯示日期
$("result_info").innerHTML = "身高: " + height * 100 + "公分, 體重: " + weight + "公斤";
$("result_bmi").innerHTML = bmi;
$("result_suggest").innerHTML = suggest;
// 呼叫showResult方法,顯示結果頁並隱藏其它頁
showResult();
}
function clear()
{
// 取得現在的日期
var t = new Date(); // t變數會存放現在時間
console.log("我想顯示的東西");
// 將日期顯示到文字框框上
$("txtDate").value = t.getFullYear() + "/" + (t.getMonth() + 1) + "/" + t.getDate();
// 清除身高跟體重欄位,input元素需透過value變數來設定
$("txtHeight").value = "";
$("txtWeight").value = "";
// 清除結果頁個元素的內容,一般元素使用innerHTML變數來設定
$("result_date").innerHTML = " ";
$("result_info").innerHTML = " ";
$("result_bmi").innerHTML = " ";
$("result_suggest").innerHTML = " ";
}
// 顯示主頁(home)並隱藏其它頁面
function showHome()
{
$("result").style.display = "none";
$("home").style.display = "block";
$("title").innerHTML = "BMI計算機";
}
// 顯示結果頁(result)並隱藏其它頁面
function showResult()
{
// 媒體查詢判斷,判斷目前解析度是位於哪個媒體查詢區間,true=最少有840px, false=低於840px
if(window.matchMedia("(min-width: 840px)").matches) return;
$("result").style.display = "block";
$("home").style.display = "none";
$("title").innerHTML = "BMI計算機-結果";
}
背景圖下載:bk.png
在行動裝置上的樣子(切換畫面)
在電腦上的樣子(分成兩欄)