JSFiddle - React, Tailwind, and code Playground
HTML
<h1 style="text-align: center;">JavaScript 系列五:第7課 ── 學會 AJAX 與 data attribute 的結合</h1>
<button id="load">Load Products</button>
<hr>
<ul></ul>
<!-- 彈跳視窗:商品詳情 -->
<div class="modal" id="detail-modal">
<div class="detail-modal-div">
<div class="pic">
<img src="" alt="">
</div>
<div class="txt">
<div class="name">
<span class="title">名稱:</span>
<span class="product-data"></span>
</div>
<div class="category">
<span class="title">分類:</span>
<span class="product-data"></span>
</div>
<div class="description">
<span class="title">描述:</span>
<span class="product-data"></span>
</div>
<div class="price">
<span class="title">價格:</span>
<span class="product-data"></span>
</div>
<div class="block-btn-group">
<button class="block-btn btn-close" onclick="closeWindow()">關閉</button>
</div>
</div>
<button class="x-btn" onclick="closeWindow()">X</button>
</div>
</div>
CSS
* {
padding: 0;
margin: 0;
list-style-type: none;
}
ul {
display: flex;
flex-wrap: wrap;
}
ul li {
width: 25%;
padding: 50px;
box-sizing: border-box;
}
ul li .img-box {
width: 100%;
height: 200px;
}
ul li .img-box img {
width: 100%;
height: 100%;
object-fit: contain;
transition: 0.5s;
}
ul li .img-box img.active {
transform: scale(1.25);
}
ul li .txt-box {
margin-top: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
height: 200px;
}
ul li .txt-box span {
text-align: center;
line-height: 1.5;
font-size: 18px;
}
ul li .txt-box button {
font-size: 16px;
display: inline-block;
padding: 10px 20px;
color: #fff;
background-color: rgba(100, 100, 255, 1);
border: none;
border-radius: 10px;
cursor: pointer;
}
#load {
display: block;
padding: 5px 10px;
margin: 10px auto;
cursor: pointer;
}
/* modal */
.modal {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(100, 100, 100, 0.7);
opacity: 0;
z-index: -1;
transition: 0.5s;
}
.modal.active {
opacity: 1;
z-index: 1;
}
.modal .detail-modal-div {
width: 1200px;
position: absolute;
padding: 20px;
background-color: #ccc;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
border-radius: 10px;
display: flex;
align-items: center;
}
.modal .detail-modal-div .pic {
margin-right: 20px;
}
.modal .detail-modal-div .pic img {
width: 250px;
object-fit: contain;
}
.modal .detail-modal-div .txt div+div {
margin-top: 20px;
}
.modal .detail-modal-div .txt .title {
font-size: 18px;
font-weight: 900;
line-height: 1.5;
}
.modal .detail-modal-div .txt .product-data {
line-height: 1.5;
}
.modal .detail-modal-div .block-btn-group {
width: 100%;
}
.block-btn {
padding: 5px 10px;
box-sizing: border-box;
width: 100%;
line-height: 30px;
font-size: 16px;
font-weight: 900;
border-radius: 10px;
...
JavaScript
let loadBtn = document.querySelector("#load");
let ul = document.querySelector("ul");
load.onclick = function loading() {
fetch("https://fakestoreapi.com/products")
.then((res) => res.json())
.then((json) => {
for (const product of json) {
let list = document.createElement("li");
let imgBox = document.createElement("div");
imgBox.classList.add("img-box");
let txtBox = document.createElement("div");
txtBox.classList.add("txt-box");
let img = document.createElement("img");
img.src = product.image;
let productNameSpan = document.createElement("span");
productNameSpan.textContent = product.title;
let detailBtn = document.createElement("button");
detailBtn.textContent = "Details";
detailBtn.onclick = function showDetails() {
let list = event.target.closest("li");
list.dataset.title = product.title;
list.dataset.category = product.category;
list.dataset.description = product.description;
list.dataset.image = product.image;
list.dataset.price = product.price;
detailModal();
};
let deleteBtn = document.createElement("button");
deleteBtn.textContent = "Delete";
deleteBtn.onclick = function deleteProduct() {
let id = product.id;
let idList = event.target.closest("li");
fetch("https://fakestoreapi.com/products/" + id, {
method: "DELETE"
})
.then((res) => res.json())
.then((json) => {
idList.remove();
})
.catch((error) => {
alert("請稍後再試");
});
};
ul.append(list);
list.append(imgBox);
list.append(txtBox);
imgBox.append(img);
txtBox.append(productNameSpan);
txtBox.append(detailBtn);
txtBox.append(deleteBtn);
...