組件實作 : Demo
Modal 指的是互動視窗,也就是讓畫面跳出一個蓋板訊息框。使用 Modal 背景大多由半透明黑色覆蓋;訊息框(互動視窗)則是垂直水平置中,應用上像是蓋板廣告,提示訊息等等,今日要實作的功能是「按下按鈕後,會跳出一個 Modal 視窗,此視窗包含一張圖片,與一小段的文字」。而在第三章,會介紹一個外掛插件 Sweet Alert 漂亮彈窗的使用方法。
本程式主要參考這裡【1】改寫。
首先,這裡要建立基本的 Modal 架構,其 HTML 的寫法如下程式碼。
HTML:
<button class="btn" id="js-btn">Open</button>
<div id="modal" class="modal">
<div class="modal__item">
<span class="close">× </span>
<img src="https://i.imgur.com/ifHvTlm.jpg" alt="" />
<p>
該圖片由<a href="https://pixabay.com/zh/users/gdmoonkiller-4679220/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=7423274">sun jib</a>在<a href="https://pixabay.com/zh//?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=7423274">Pixabay</a>上發布
</p>
</div>
</div>
最外層定義一個 Class 名稱為modal
的 div,用於版面配置,而 Class 名稱為modal__item
的 div ,modal__item
裡面包含所有 modal 相關的元素,像是圖片與一小段文字,其中比較特別的用法應該是 span 元素中的×
,代表意思是一個 x 符號。
顯示結果:
加入起手式,調整整個畫布的範圍,這裡稍微更新起手式的寫法,像是加入box-sizing: border-box;
用法,以及將 body 和 html 寫在一起,方便管理。
CSS:
* {
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
新增起手式相關語法。
顯示結果:
由於圖片原始像素為 1920 *1280,超出 modal 的範圍,這裡我們將圖片寬度設定為 100%,使其填滿整個 modal。再來是 modal 本身的樣式修改,程式碼如下。
CSS:
img {
width: 100%;
object-fit: cover;
}
.modal {
width: 100%;
height: 100%;
padding: 5px;
box-shadow: 0 3px 4px rgba(0, 0, 0, 0.1), 0 1px 8px rgba(0, 0, 0, 0.05),
0 2px 20px rgba(0, 0, 0, 0.1);
background-color: rgba(0, 0, 0, 0.4);
position: fixed;
left: 0;
top: 0;
z-index: 1;
overflow: auto;
/* display: none; */
}
modal 功能就像是 Card 一樣,用來當作放置元素的面板。其中的box-shadow
套用「Day 07:Card 組件實作」篇的參數。這裡的background-color
則是設定黑色透明度,營造出覆蓋時的遮罩感覺。position
設定成 fixed 讓整個面板可以固定在畫面上,這裡固定從左上角開始。這裡要注意的是display: none;
為預設, 當 Buttotn 被點擊後,display 會被設定成 block,意即display: block;
。
顯示結果:
關於
overflow : auto
沒有說明到,這裡補上相關參數的用法。
在 HTML 裡有一個 span 元素(Class 名稱為 close),這個元素用來處理關閉 modal 的事件,事件的處理會使用 JavaScript 來實作,這裡的 close 主要處理 span 元素的樣式與排版,程式碼如下。
CSS:
.close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
顯示結果:
使用之前寫過的 Button 樣式,這裡只要套用就好。
CSS:
.btn {
width: 160px;
height: 64px;
background-image: linear-gradient(
135deg,
#6555a0 0%,
#578aef 55%,
#8f41e9 100%
);
border-radius: 8px;
border: none;
color: white;
font-size: 28px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
.btn:hover {
cursor: pointer;
box-shadow: 5px 0 10px rgb(117, 117, 117);
}
顯示結果:
記得要在
modal
裡面設定display: none
,才會顯示 Button,因為 modal 的z-index: 1;
,所以會覆蓋住 Button 按鈕。
這裡主要功能是開啟原本被隱藏的modal
,修改方式則是使用modal.style.display
的block
和none
做切換,讓面板達到開起或是關閉的效果,程式碼實作如下。
JavaScript:
let modal = document.getElementById("modal");
let btn = document.getElementById("js-btn");
let span = document.getElementsByClassName("close")[0];
btn.addEventListener("click", btnfn, false);
span.addEventListener("click", spanfn, false);
function btnfn() {
modal.style.display = "block";
}
function spanfn() {
modal.style.display = "none";
}
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
宣告三個變數 modal、btn 和 span,modal 主要是面板的控制,也就是更夠將 CSS 中 .modal 的 display 作切換。btn 主要式處理按鈕按下時,會開啟覆蓋面板,span 是 close 的功能,也就是點擊右上角叉叉來關閉視窗。特別注意的地方是window.onclick
用法,它的用途是能夠關閉 modal 視窗的非元素位置的區域,意思就是說,不需要點選叉叉的按鈕即可關閉覆蓋面板。
顯示結果:
可先到套件的官網:SweetAlert2。
談到提示視窗,應該多多少少都會聽過 SweetAlert 這個套件才是,可以把它想像成是一個經過美化面板。值得注意的是,此套件有分為 SweetAlert 和 SweetAlert2 兩種,差別在於 SweetAlert 的更新頻率低於 SweetAlert2,並且比起 SweetAlert,SweetAlert2 操作更加簡單,上述種種原因,本篇文章決定採用 SweetAlert2 來實作。
這裡有 jQuery 和 SweetAlert2 的 CDN 要加入。
HMTL:(jQuery套件jquery.min.js
)
<!-- jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
HTML:(SweetAlert2 套件sweetalert2.all.min.js
)
<!-- SweetAlert2 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/7.2.0/sweetalert2.all.min.js"></script>
Class 名稱設為 button,這個 Class 用途是用來修改 Button 的樣式,而 ID 為 success,它的用途是用來執行按鈕點擊時要做的事情(點擊按鈕會彈出 SweetAlert2 的確認視窗)。
HTML:
<button id="success" class="button"> Success </button>
CSS:
CSS 的部分,可以參考之前 Button 組件實作那一篇文章有介紹的 Button Optimizer,可以直接複製貼上 Code,參數的用法在那篇文章有解釋過,有興趣可以先回去看看~
.button {
display: inline-block;
text-align: center;
vertical-align: middle;
padding: 12px 42px;
border: 1px solid #398d52;
border-radius: 5px;
background: #5ee887;
background: -webkit-gradient(
linear,
left top,
left bottom,
from(#5ee887),
to(#398d52)
);
background: -moz-linear-gradient(top, #5ee887, #398d52);
background: linear-gradient(to bottom, #5ee887, #398d52);
-webkit-box-shadow: #62f28c 0px 0px 40px 0px;
-moz-box-shadow: #62f28c 0px 0px 40px 0px;
box-shadow: #62f28c 0px 0px 40px 0px;
text-shadow: #29653b 3px 5px 2px;
font: italic normal bold 30px arial;
color: #ffffff;
text-decoration: none;
text-transform: uppercase;
}
.button:hover {
border: 1px solid ##52ca75;
background: #71ffa2;
background: -webkit-gradient(
linear,
left top,
left bottom,
from(#71ffa2),
to(#44a962)
);
background: -moz-linear-gradient(top, #71ffa2, #44a962);
background: linear-gradient(to bottom, #71ffa2, #44a962);
color: #ffffff;
text-decoration: none;
text-transform: uppercase;
}
.button:active {
background: #398d52;
background: -webkit-gradient(
linear,
left top,
left bottom,
from(#398d52),
to(#398d52)
);
background: -moz-linear-gradient(top, #398d52, #398d52);
background: linear-gradient(to bottom, #398d52, #398d52);
text-transform: uppercase;
}
.button:focus {
text-transform: uppercase;
}
.button:before {
content: "\0000a0";
display: inline-block;
height: 24px;
width: 24px;
line-height: 24px;
margin: 0 4px -6px -4px;
position: relative;
top: 0px;
left: 0px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAA7EAAAOxAGVKw4bAAADOklEQVRIibWVT2wUVRzHP7/3ZobZNcEtEiEubiQxHkijtAGNrK4eTLxxIohJJZpAY7yoiGlIiASsRFJOBEzcejB4wJhejMYQQkgVBYwixeAfTK21sg1/Ygtt2W53Z97zMFC23ZnaHvjd5r3f7/v5ft9M3sBdLmlY+eBvtOsUgPvDrdme+YioHb1tKHXVNGWOsf3RZIDuLuWALmADEABrw63Zn+cU33lyDbXqaUCh1Fdo/ZbpLPwxA6C6L6UF6QC2A+m6+eNYng/bsyZWfPcZxeTk11jzVN1yFaUP4rq7zZ78mIoosgV4Z5Y4wHMI6xPtT01tnCUO4GHCbdSq7QAKAEsPcD1BpksXS36D+z2n05hwX/yITOA4PdOAsD07DLyXAHgY4Y2G1cpUB9bmYieU6jLvPj14J0EU4wDQnwDp0MXSA9PzO08+hDHb4s3LEL6/f/qxfk93l9YDnydAPg6d6isMXkFVJ49gzKbYLu28aPY+8+m0mfo9K/ZL4GgCoE0H3uMqqBYwZmNsh1LfkE59NiNQg4FiqRnhLODFSJyyf170sbY1Zi/AdZ80nYUfZzBnd4Xt2QtAMSHFugRxUOrwbHEAJ7bZ2l2IbAKWKrG8kP2OV1ceozUzgPp9hPPjKygO5Tn8z1pCq0BkDNfbESfVeBfdKt1des2R8FCx5UM253qxFYO9GRD8NIo0eUhK03OlhZf72qiJ97bZ++z+OJ2GI6qL8VHnqiO/bs71Yq5OEQ5MYC5XCC6OU/t+hPBSmQ3LzvH+qi/6cb2DSSqJCey1vA/8ZceD5eFQGZSgcylqP4wSXLgBgNvahGTcEXz9oPtEX3mBCXgEWG5u1CInniBpB3HveAovV8CyhNA2J4nMBVgcqdgoUcVgyyG2vqN665INbMNdNQ+AHQACSemoMeMi92hUxkOtSEWp7nUBDIvU0MIBimHghFrigauw5TB62YM3saM1JK3R2RQovhVfLxwg950CeBNHrjsr0+BrzL9VzPAkstjBaWkCRybQ8rrz2NnYHxLM8RXdLnstvxr4BGgGCH4Zuz3Zj6NecvPnz8w1/7+ACLLOAykAq4Pfxn00fbJIH3fWnKvMZ/6u1n/XEB6mYgjirQAAAABJRU5ErkJggg==")
no-repeat left center transparent;
background-size: 100% 100%;
}
顯示結果:
SweetAlert2 的用法也是參考範例,然後調整成你需要的樣子,這裡參考How to use and customize 這個範例,修改成我們需要的樣子。
JavaScript:
let btn = document.getElementById("success");
btn.addEventListener("click", success__fn, false);
function success__fn() {
// swal(
// "Success",
// 'You clicked the <b style="color:green;">Success</b> button!',
// "success"
// );
swal({
title: "呵!",
text: "圖:SPY x FAMILY官方推特",
imageUrl: "https://i.imgur.com/1BMhKOB.jpg",
imageWidth: 540,
imageHeight: 303,
imageAlt: "Custom image",
animation: true
});
}
swal 可以直接放進監聽事件的 Function 中,swal 的物件裡面可以放入預設的參數,只需輸入對應的參數值即可直接使用。
註解的地方可以打開來看看,它是另外一個例子。
顯示結果:
本篇實作了蓋板互動視窗的寫法,以及介紹了一款 SweetAlert2 套件的操作 SOP,不論是自己動手實作,或者是直接使用 SweetAlert2 套件,都可以達到相同的目的,至於要使用哪種方式,必須交給開發者自行取捨,以上為本篇的所有內容,謝謝收看!