iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0

https://i.imgur.com/YObOHNb.jpg

組件實作 : Demo

一、前言

Modal 指的是互動視窗,也就是讓畫面跳出一個蓋板訊息框。使用 Modal 背景大多由半透明黑色覆蓋;訊息框(互動視窗)則是垂直水平置中,應用上像是蓋板廣告,提示訊息等等,今日要實作的功能是「按下按鈕後,會跳出一個 Modal 視窗,此視窗包含一張圖片,與一小段的文字」。而在第三章,會介紹一個外掛插件 Sweet Alert 漂亮彈窗的使用方法。

本程式主要參考這裡【1】改寫。


二、直接實作 Modal 組件

2.1 Modal 的 HTML 架構

首先,這裡要建立基本的 Modal 架構,其 HTML 的寫法如下程式碼。

HTML:

<button class="btn" id="js-btn">Open</button>
<div id="modal" class="modal">
	<div class="modal__item">
		<span class="close">&times </span>
		<img src="https://i.imgur.com/ifHvTlm.jpg" alt="" />
		<p>
			該圖片由<a href="https://pixabay.com/zh/users/gdmoonkiller-4679220/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=7423274">sun jib</a>在<a href="https://pixabay.com/zh//?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=7423274">Pixabay</a>上發布
		</p>
	</div>
</div>

最外層定義一個 Class 名稱為modal的 div,用於版面配置,而 Class 名稱為modal__item的 div ,modal__item裡面包含所有 modal 相關的元素,像是圖片與一小段文字,其中比較特別的用法應該是 span 元素中的&times,代表意思是一個 x 符號。

顯示結果:

https://i.imgur.com/J8KP615.jpg

2.2 CSS 起手式

加入起手式,調整整個畫布的範圍,這裡稍微更新起手式的寫法,像是加入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;
}

新增起手式相關語法。

顯示結果:

https://i.imgur.com/JhMNIpz.jpg

2.3 modal 樣式與排版

由於圖片原始像素為 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;

顯示結果:

https://i.imgur.com/cCMFqjP.jpg

關於overflow : auto沒有說明到,這裡補上相關參數的用法

2.4 Close 關閉視窗按鈕

在 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;
}

顯示結果:

https://i.imgur.com/fA1jCJT.gif

2.5 Button 樣式

使用之前寫過的 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);
}

顯示結果:

https://i.imgur.com/y7vTVfC.jpg

記得要在 modal裡面設定display: none,才會顯示 Button,因為 modal 的z-index: 1;,所以會覆蓋住 Button 按鈕。

2.6 JavaScript 開啟覆蓋面板功能

這裡主要功能是開啟原本被隱藏的modal,修改方式則是使用modal.style.displayblocknone做切換,讓面板達到開起或是關閉的效果,程式碼實作如下。

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 視窗的非元素位置的區域,意思就是說,不需要點選叉叉的按鈕即可關閉覆蓋面板。

顯示結果:

https://i.imgur.com/O4185De.gif


三、 SweetAlert2 套件

可先到套件的官網:SweetAlert2

談到提示視窗,應該多多少少都會聽過 SweetAlert 這個套件才是,可以把它想像成是一個經過美化面板。值得注意的是,此套件有分為 SweetAlert 和 SweetAlert2 兩種,差別在於 SweetAlert 的更新頻率低於 SweetAlert2,並且比起 SweetAlert,SweetAlert2 操作更加簡單,上述種種原因,本篇文章決定採用 SweetAlert2 來實作。

3.1 選擇 CDN

這裡有 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>

3.2 加入一個 Button 按鈕

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%;
}

顯示結果:

https://i.imgur.com/IMlq3U8.jpg

3.4 SweetAlert2 功能實作

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 的物件裡面可以放入預設的參數,只需輸入對應的參數值即可直接使用。

註解的地方可以打開來看看,它是另外一個例子。

顯示結果:

https://i.imgur.com/gJRoyy8.gif


四、推薦資源

  1. Modal · Bootstrap v5.2
  2. SweetAlert
  3. SweetAlert2

五、結論

本篇實作了蓋板互動視窗的寫法,以及介紹了一款 SweetAlert2 套件的操作 SOP,不論是自己動手實作,或者是直接使用 SweetAlert2 套件,都可以達到相同的目的,至於要使用哪種方式,必須交給開發者自行取捨,以上為本篇的所有內容,謝謝收看!


六、參考資料

  1. How TO - CSS/JS Modal
  2. How to use and customize

上一篇
Day 11:Timeline 組件實作
下一篇
Day 13:Tab 組件實作
系列文
從零開始手刻網站,30 天打造我的前端武器庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言