前言
本文將展示一段結合 HTML、CSS 和 JavaScript 的代碼,實現了一個簡單的商品展示頁面及商品詳情,涵蓋數據獲取、渲染、搜索及排序等功能。
效果展示
點擊不同的商品會展示對應的商品詳情。
?代碼部分
代碼總體實現
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport"content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><title></title><style>* {margin: 0;padding: 0;}#title {width: 100%;height: 50px;background-color: white;font-weight: 800;font-size: 19px;display: flex;justify-content: center;align-items: center;position: fixed;z-index: 1;margin-top: -10px;}#searchContent {width: 95%;margin-left: 2%;height: 4vh;position: relative;}#searchContent input {margin-top: 50px;width: 100%;height: 100%;border-radius: 50px;/* border-style: none; *//* background-color: lightgray; */display: inline-block;}input::placeholder {color: gray;font-size: 16px;text-align: center;}#searchContent img {margin-top: 50px;position: absolute;width: 9%;height: 100%;top: 4px;right: 10px;}#productContent {/* margin-top: 50px; */column-count: 2;column-gap: 10px;padding: 10px;}#product {break-inside: avoid;width: 100%;margin-bottom: 10px;/* background-color: ; */box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);/* padding: 10px; */}#product img {width: 100%;height: auto;}#product div {/* width: 96%; */text-align: center;/* height: 2vh; */margin-left: 2%;margin-top: 0;font-size: 10px;}#name {font-size: 19px;font-weight: 700;}#info {font-weight: 400;/* height: 30px; *//* background-color: blue; */font-size: 15px;width: 100%;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;overflow: hidden;text-overflow: ellipsis;}#product p {margin-left: 2%;margin-bottom: 0;/* color: #666; */color: red;font-size: 20px;}#titles {background-color: orangered;border-radius: 10px;color: yellow;width: 45px;padding: 3px;font-weight: 600;}#orderBut {margin-top: 60px;padding: 5px;}#noResult {text-align: center;font-size: 18px;color: gray;margin-top: 50px;}</style></head><body><div id="title">主頁</div><!-- 搜索框部分 --><div id="searchContent"><input id="searchInput" style="text-align: center;font-size: 16px;" type="text" placeholder="搜索框" /><img src="./img/sousuo.png" /></div><div><button id="orderBut">排序</button></div><!-- 內容區域 --><div id="productContent"><!-- 商品部分 --><div id="product"><!-- 商品圖片 --><div id="imgBox"><img src="" /></div><!-- 商品名字 --><div id="name"></div><!-- 商品詳情 --><div>統一</div><!-- 簡介 --><div>方便面</div><!-- 價錢 --><p>¥16.44</p></div></div><script>let data;let productContent = document.getElementById('productContent');let searchInput = document.getElementById('searchInput'); // 獲取搜索框輸入元素let originalData;// 發起請求獲取數據的代碼部分保持不變let xhr = new XMLHttpRequest();xhr.open('get', './js/productAbout.json', true);xhr.send();xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {let text = xhr.responseText;data = JSON.parse(text);// 把data數據賦值給originalData,用于輸入框清空后顯示原始的數據originalData = data;//渲染originalDatarender(originalData);}};function render(data) {let str = "";for (let i in data) {str += `<div id="product"><div id="imgBox" onclick="jumpPage(${i})"><img src="${data[i].img[0]}" /></div><div id="name">${data[i].name}</div><h3 id="info">${data[i].info}</h3><div id="titles">${data[i].about}</div><p>${data[i].prise}</p></div>`}document.getElementById('productContent').innerHTML = str};// 詳情頁跳轉函數保持不變function jumpPage(index) {localStorage.setItem('details', JSON.stringify(data[index]))window.location.href = './shopAbout.html';}//==========================模糊搜索============================// 先獲取輸入框元素let input = document.getElementById('searchInput');//給輸入框上事件監聽 input.addEventListener('input', function() {//用于下面往里面拼東西let str_content = '';//判斷輸入框里的值let searchValue = input.value.trim()//如果值為空if (searchValue === "") {// 把data數據賦值給originalDataoriginalData = data;} else {//聲明originalData為空數組originalData = [];//值不為空的話(說明我往輸入框里輸入東西了),就循環data數據for (let i in data) {//檢查data數組中(namez值info值prise值)是否包括搜索框(searchValue)輸入的值if (data[i].name.includes(searchValue) || data[i].info.includes(searchValue) || data[i].prise.includes(searchValue)) {//把data數據的下標i的數據插入到originalData中originalData.push(data[i]);}}}//如果搜索不到if (originalData.length === 0) {// 如果經過篩選后originalData數組為空,說明沒有找到符合搜索條件的數據str_content = '<div id="noResult">無符合條件的內容</div>';//否則就是搜索到了} else {// 如果找到了符合條件的數據,就按照原來的邏輯拼接字符串(上面的)for (let i in originalData) {str_content += `<div id="product"><div id="imgBox" onclick="jumpPage(${i})"><img src="${originalData[i].img[0]}" /></div><div id="name">${originalData[i].name}</div><h3 id="info">${originalData[i].info}</h3><div id="titles">${originalData[i].about}</div><p>${originalData[i].prise}</p></div>`;}}// 獲取商品展示區域的元素,假設其id為productContentlet productContent = document.getElementById('productContent');productContent.innerHTML = str_content;});// //最后渲染上去// render(originalData);// })//========================排序==================//獲取按鈕let orderBut = document.getElementById('orderBut');//初始化次數為零let num = 0;//給按鈕上點擊事件orderBut.onclick = function() {//次數+1num++;//如果次數等于1 的時候if (num == 1) {//用sort排序originalData = originalData.sort(function(a, b) {//反值a-b的價錢//如果 a.prise - b.prise 的計算結果小于 0,//即 a 的 prise 值小于 b 的 prise 屬性值,此時 a 會排在 b 的前面。return a.prise - b.prise;});console.log(data);//次數等于2的時候//當 b.prise - a.prise 的值小于 0 時,//就是 b 的 prise 屬性值小于 a 的 prise 屬性值,此時 b 元素會排在 a 元素前面} else if (num == 2) {originalData = originalData.sort(function(a, b) {return b.prise - a.prise;});} else if (num == 3) {num = 0;//展開語法(...),將 data 數組中的元素逐個復制到 originalData 數組中,相當于重置originalData = [...data]}//渲染render(originalData);};</script></body>
</html>
代碼詳解
HTML
<div id="title">主頁</div><!-- 搜索框部分 --><div id="searchContent"><input id="searchInput" style="text-align: center;font-size: 16px;" type="text" placeholder="搜索框" /><img src="./img/sousuo.png" /></div><div><button id="orderBut">排序</button></div><!-- 內容區域 --><div id="productContent"><!-- 商品部分 --><div id="product"><!-- 商品圖片 --><div id="imgBox"><img src="" /></div><!-- 商品名字 --><div id="name"></div><!-- 商品詳情 --><div>統一</div><!-- 簡介 --><div>方便面</div><!-- 價錢 --><p>¥16.44</p></div></div>
CSS
* {margin: 0;padding: 0;}#title {width: 100%;height: 50px;background-color: white;font-weight: 800;font-size: 19px;display: flex;justify-content: center;align-items: center;position: fixed;z-index: 1;margin-top: -10px;}#searchContent {width: 95%;margin-left: 2%;height: 4vh;position: relative;}#searchContent input {margin-top: 50px;width: 100%;height: 100%;border-radius: 50px;/* border-style: none; *//* background-color: lightgray; */display: inline-block;}input::placeholder {color: gray;font-size: 16px;text-align: center;}#searchContent img {margin-top: 50px;position: absolute;width: 9%;height: 100%;top: 4px;right: 10px;}#productContent {/* margin-top: 50px; */column-count: 2;column-gap: 10px;padding: 10px;}#product {break-inside: avoid;width: 100%;margin-bottom: 10px;/* background-color: ; */box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);/* padding: 10px; */}#product img {width: 100%;height: auto;}#product div {/* width: 96%; */text-align: center;/* height: 2vh; */margin-left: 2%;margin-top: 0;font-size: 10px;}#name {font-size: 19px;font-weight: 700;}#info {font-weight: 400;/* height: 30px; *//* background-color: blue; */font-size: 15px;width: 100%;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;overflow: hidden;text-overflow: ellipsis;}#product p {margin-left: 2%;margin-bottom: 0;/* color: #666; */color: red;font-size: 20px;}#titles {background-color: orangered;border-radius: 10px;color: yellow;width: 45px;padding: 3px;font-weight: 600;}#orderBut {margin-top: 60px;padding: 5px;}#noResult {text-align: center;font-size: 18px;color: gray;margin-top: 50px;}
JS
總覽
let data;let productContent = document.getElementById('productContent');let searchInput = document.getElementById('searchInput'); // 獲取搜索框輸入元素let originalData;// 發起請求獲取數據的代碼部分保持不變let xhr = new XMLHttpRequest();xhr.open('get', './js/productAbout.json', true);xhr.send();xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {let text = xhr.responseText;data = JSON.parse(text);// 把data數據賦值給originalData,用于輸入框清空后顯示原始的數據originalData = data;//渲染originalDatarender(originalData);}};function render(data) {let str = "";for (let i in data) {str += `<div id="product"><div id="imgBox" onclick="jumpPage(${i})"><img src="${data[i].img[0]}" /></div><div id="name">${data[i].name}</div><h3 id="info">${data[i].info}</h3><div id="titles">${data[i].about}</div><p>${data[i].prise}</p></div>`}document.getElementById('productContent').innerHTML = str};// 詳情頁跳轉函數保持不變function jumpPage(index) {localStorage.setItem('details', JSON.stringify(data[index]))window.location.href = './shopAbout.html';}//==========================模糊搜索============================// 先獲取輸入框元素let input = document.getElementById('searchInput');//給輸入框上事件監聽 input.addEventListener('input', function() {//用于下面往里面拼東西let str_content = '';//判斷輸入框里的值let searchValue = input.value.trim()//如果值為空if (searchValue === "") {// 把data數據賦值給originalDataoriginalData = data;} else {//聲明originalData為空數組originalData = [];//值不為空的話(說明我往輸入框里輸入東西了),就循環data數據for (let i in data) {//檢查data數組中(namez值info值prise值)是否包括搜索框(searchValue)輸入的值if (data[i].name.includes(searchValue) || data[i].info.includes(searchValue) || data[i].prise.includes(searchValue)) {//把data數據的下標i的數據插入到originalData中originalData.push(data[i]);}}}//如果搜索不到if (originalData.length === 0) {// 如果經過篩選后originalData數組為空,說明沒有找到符合搜索條件的數據str_content = '<div id="noResult">無符合條件的內容</div>';//否則就是搜索到了} else {// 如果找到了符合條件的數據,就按照原來的邏輯拼接字符串(上面的)for (let i in originalData) {str_content += `<div id="product"><div id="imgBox" onclick="jumpPage(${i})"><img src="${originalData[i].img[0]}" /></div><div id="name">${originalData[i].name}</div><h3 id="info">${originalData[i].info}</h3><div id="titles">${originalData[i].about}</div><p>${originalData[i].prise}</p></div>`;}}// 獲取商品展示區域的元素,假設其id為productContentlet productContent = document.getElementById('productContent');productContent.innerHTML = str_content;});// //最后渲染上去// render(originalData);// })//========================排序==================//獲取按鈕let orderBut = document.getElementById('orderBut');//初始化次數為零let num = 0;//給按鈕上點擊事件orderBut.onclick = function() {//次數+1num++;//如果次數等于1 的時候if (num == 1) {//用sort排序originalData = originalData.sort(function(a, b) {//反值a-b的價錢//如果 a.prise - b.prise 的計算結果小于 0,//即 a 的 prise 值小于 b 的 prise 屬性值,此時 a 會排在 b 的前面。return a.prise - b.prise;});console.log(data);//次數等于2的時候//當 b.prise - a.prise 的值小于 0 時,//就是 b 的 prise 屬性值小于 a 的 prise 屬性值,此時 b 元素會排在 a 元素前面} else if (num == 2) {originalData = originalData.sort(function(a, b) {return b.prise - a.prise;});} else if (num == 3) {num = 0;//展開語法(...),將 data 數組中的元素逐個復制到 originalData 數組中,相當于重置originalData = [...data]}//渲染render(originalData);};
JS詳解
- 變量聲明:
data
:用于存儲從?./js/productAbout.json
?文件獲取并解析后的商品數據。productContent
:獲取頁面上商品展示區域的,后續用于更新商品展示內容。searchInput
:獲取搜索框的 DOM 元素,監聽輸入事件。originalData
:用于存儲原始商品數據,在搜索和排序操作中作為基礎數據使用。
let data;
let productContent = document.getElementById('productContent');
let searchInput = document.getElementById('searchInput');
let originalData;
- 數據請求:
- 使用?
XMLHttpRequest
?對象發送 GET 請求到?./js/productAbout.json
?文件。 - 當請求成功(
readyState
?為 4 且?status
?為 200)時,將響應文本解析為 JSON 格式并賦值給?data
。 - 將?
data
?賦值給?originalData
,并調用?render
?函數渲染原始數據。
- 使用?
let xhr = new XMLHttpRequest();
xhr.open('get', './js/productAbout.json', true);
xhr.send();
xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {let text = xhr.responseText;data = JSON.parse(text);originalData = data;render(originalData);}
};
- 數據渲染函數:
- 該函數用于將商品數據渲染到頁面上。
- 初始化一個空字符串?
str
,通過?for...in
?循環遍歷?data
?數組。 - 為每個商品拼接 HTML 字符串,包括商品圖片、名稱、詳情、簡介和價格等信息,并為商品圖片添加點擊事件?
jumpPage(${i})
,其中?i
?為商品在數組中的索引。 - 最后將拼接好的 HTML 字符串設置為?
productContent
?的?innerHTML
,從而在頁面上顯示商品。
function render(data) {let str = "";for (let i in data) {str += `<div id="product"><div id="imgBox" onclick="jumpPage(${i})"><img src="${data[i].img[0]}" /></div><div id="name">${data[i].name}</div><h3 id="info">${data[i].info}</h3><div id="titles">${data[i].about}</div><p>${data[i].prise}</p></div>`}document.getElementById('productContent').innerHTML = str
};
- 詳情頁跳轉函數:
- 當用戶點擊商品圖片時,該函數被調用。
- 它將當前點擊商品的數據(
data[index]
)以 JSON 字符串的形式存儲在本地存儲中,鍵為?details
。 - 然后將頁面導航到?
./shopAbout.html
,通常這個頁面會從本地存儲中讀取商品詳情數據并展示。
function jumpPage(index) {localStorage.setItem('details', JSON.stringify(data[index]))window.location.href = './shopAbout.html';
}
- 模糊搜索功能:
- 獲取搜索框元素并添加?
input
?事件監聽器,當用戶在搜索框中輸入內容時觸發。 - 初始化一個空字符串?
str_content
?用于存儲搜索結果的 HTML 內容,獲取并修剪搜索框的值?searchValue
。 - 如果搜索框為空,將?
originalData
?重置為原始的?data
。否則,清空?originalData
?數組,遍歷?data
?數組,檢查商品的名稱、詳情或價格是否包含搜索值,若包含則將該商品添加到?originalData
?中。 - 如果?
originalData
?數組為空,說明沒有找到符合條件的商品,設置?str_content
?為提示信息。否則,遍歷?originalData
?數組,拼接符合條件的商品的 HTML 內容。 - 最后更新?
productContent
?的?innerHTML
?以顯示搜索結果。
- 獲取搜索框元素并添加?
let input = document.getElementById('searchInput');
input.addEventListener('input', function() {let str_content = '';let searchValue = input.value.trim()if (searchValue === "") {originalData = data;} else {originalData = [];for (let i in data) {if (data[i].name.includes(searchValue) || data[i].info.includes(searchValue) || data[i].prise.includes(searchValue)) {originalData.push(data[i]);}}}if (originalData.length === 0) {str_content = '<div id="noResult">無符合條件的內容</div>';} else {for (let i in originalData) {str_content += `<div id="product"><div id="imgBox" onclick="jumpPage(${i})"><img src="${originalData[i].img[0]}" /></div><div id="name">${originalData[i].name}</div><h3 id="info">${originalData[i].info}</h3><div id="titles">${originalData[i].about}</div><p>${originalData[i].prise}</p></div>`;}}let productContent = document.getElementById('productContent');productContent.innerHTML = str_content;
});
- 排序功能
- 獲取 “排序” 按鈕元素,并初始化一個計數器?
num
?為 0。 - 為按鈕添加點擊事件,每次點擊?
num
?自增 1。 - 當?
num
?為 1 時,使用?sort
?方法對?originalData
?進行升序排序,比較商品價格?prise
。 - 當?
num
?為 2 時,進行降序排序。 - 當?
num
?為 3 時,將?num
?重置為 0,并通過展開運算符將?data
?數組的內容復制給?originalData
,恢復原始順序。 - 最后調用?
render
?函數,根據排序后的?originalData
?重新渲染商品展示區域。
- 獲取 “排序” 按鈕元素,并初始化一個計數器?
let orderBut = document.getElementById('orderBut');
let num = 0;
orderBut.onclick = function() {num++;if (num == 1) {originalData = originalData.sort(function(a, b) {return a.prise - b.prise;});} else if (num == 2) {originalData = originalData.sort(function(a, b) {return b.prise - a.prise;});} else if (num == 3) {num = 0;originalData = [...data]}render(originalData);
};
商品詳情部分
代碼部分
代碼總體實現
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport"content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><title></title><style>* {margin: 0;padding: 0;}.return {width: 100%;/* height: 45px; */background-color: white;font-weight: 800;font-size: 19px;display: flex;/* justify-content: space-between; */align-items: center;position: fixed;z-index: 1;/* margin-top: -10px; */}.return p {/* margin-left: auto; *//* position: absolute; */margin-left: 36%;}.return img {width: 7%;}/* 定義輪播圖底板大小 */.banner {width: 100%;/* height: 700px; *//* margin-top: 6vh; *//* margin: auto; *//* border: 5px solid blue; *//* 將多余部分隱藏 */overflow: hidden;font-size: 0;}/* 規定容器里圖片規格 */.box img {width: 25%;height: 40vh;/* float: left; *//* display: inline-block; */}/* 包著圖片的容器大小 */.box {width: 400%;margin-top: 26px;/* height: 700px; *//* 動畫效果運用到每個圖片身上 *//* ---名字--持續時間--動畫播放次數=無限 */animation: donghua 13s infinite;}/* 當在 @keyframes 創建動畫,把它綁定到一個選擇器,否則動畫不會有任何效果。 */@keyframes donghua {/* 0% 是動畫的開始,100% 是動畫的完成。 */0% {margin-left: 0;}33.33% {/* 向左移負的1885px。因為上面規定的一張圖片的大小是1885px */margin-left: -100%;}66.66% {margin-left: -200%;}100% {margin-left: -300%;}}.priseContent {display: flex;justify-content: space-between;width: 100%;/* height: 60px; */background-color: #ff1e21;}.deja {/* display: inline-block; */}.price {margin-left: 10px;}.priceWord {/* display: inline-block; */background-color: #eb0003;padding: 6px;font-size: 17px;color: white;}.nowPrice {font-size: 25px;color: white;/* margin-left: 10px; */}.infoProduct {width: 96%;margin-left: 2%;margin-top: 5px;}#freeBuy {color: darkgray;}#infoProduct {color: #eb0003;font-weight: 400;}.infoProduct p {color: #eb0003;font-size: 20px;font-weight: 700;}.infoImg img {width: 100%;}.infoImg {/* height: 150vh; */width: 96%;margin-left: 2%;}.line {width: 100%;height: 5px;background-color: lightgray;margin-top: 5px;}.bottonContent {width: 100%;height: 70px;background-color: cadetblue;}/* /底部板子 */.foot-center {width: 100%;display: flex;position: fixed;bottom: 0;z-index: 1;justify-content: space-around;background-color: white;margin-top: 15%;height: 50px;}/* 小塊 */.chef {display: flex;flex-direction: column;text-align: center;width: 48px;height: 100%;font-size: 13px;font-weight: 100;margin-bottom: 5px;margin-top: 5px;}.foot-center img {width: 18px;height: 18px;}.kong {width: auto;height: 100px;}.buy {display: flex;align-items: center;justify-content: center;background-color: red;border-radius: 50px;padding-left: 70px;padding-right: 70px;color: white;margin-bottom: 5px;margin-top: 5px;/* margin-left: 50px; */}#wide {height: 10vh;}</style></head><body><!-- 大底板 --><div class="aboutContent"><!-- 返回按鍵 --><div class="return"><img src="./img/jiantou.png" /><p>詳情頁</p></div><!-- 輪播圖 --><div class="banner"><div class="box"><!-- 圖1 --><img src="./img/iwtch.jpg" /><!-- 圖2 --><img src="./img/watch3.jpg" /><!-- 圖3 --><img src="./img/watch2.jpg" /><!-- 重復圖1 --><img src="./img/iwtch.jpg" /></div></div><!-- 價格橫條 --><!-- 詳情 --><div class="infoProduct"><!-- 名字 --><div id="infoProduct"></div><!-- 詳情 --><h3></h3><!-- 包郵 --><div></div><!-- 價格 --><p></p></div><!-- 分割線 --><div class="line"></div><!-- 圖片詳情 --><div class="infoImg"></div><div id="wide"></div><!-- 底部導航 --><div class="foot"><!-- 底部板子 --><div class="foot-center"><!-- 主頁 --><div class="chef"><div class="chef-logo"><img src="./img/home.png" alt="" /></div>主頁</div><!-- 分享 --><div class="chef"><div class="chef-logo"><img src="./img/about.png" alt="" /></div>分享</div><!-- 我的 --><div class="chef"><div class="chef-logo"><img src="./img/my.png" alt="" /></div>我的</div><!-- 購買 --><div class="buy"><div class="buy-logo"></div>立即購買</div></div></div></div><script>// 回主頁的點擊事件let returnHome = document.getElementsByClassName('chef-logo')[0];returnHome.onclick = function() {window.location.href = './shop.html';}// 回主頁的點擊事件let returnLeft = document.getElementsByClassName('return')[0];returnLeft.onclick = function() {window.location.href = './shop.html';}//通過鍵名details在詳情頁獲取在主頁存的數據//它的作用是將一個 JSON 格式的字符串解析為 JavaScript 對象let data = JSON.parse(localStorage.getItem('details'));console.log(data);//先聲明一個空字符串let str = "";//拼接字符串(根據json中的數據拼)//如果想給他改樣式 需要在拼接字符串里命名 然后在用名字改樣式str += `<div id="aboutContent"><div id="infoProduct">${data.name}</div><h3>${data.info}</h3><div id="freeBuy">${data.about}</div><p>${data.prise}</p>`//獲取商品的詳情部分,并把拼好的str寫進去document.getElementsByClassName('infoProduct')[0].innerHTML = str;//渲染函數(為了渲染圖片的)function render() {//=========================輪播圖的圖片拼接=========================//聲明一個空的字符串let imgStr = ""//使用for循環去遍歷img數組(json里的)for (let i = 0; i < data.img.length; i++) {// 每次循環都把當前的img下標往imgstr字符串里面拼imgStr += `<img src = "${data.img[i]}"/> `}// 首張圖片在展示時有重復顯示的效果imgStr += `<img src = "${data.img[0]}"/>`//獲取輪播圖的box容器 并把拼好的字符串(imgStr)寫進去document.getElementsByClassName('box')[0].innerHTML = imgStr;//=========================詳情的圖片拼接=========================//聲明一個空的字符串let infoImgStr = ""//使用for循環去遍歷img數組(json里的)for (let j = 0; j < data.infoImg.length; j++) {// 每次循環都把當前的img下標往infoImgStr字符串里面拼infoImgStr += `<img src = "${data.infoImg[j]}"/>`}//獲取詳情照片的infoImg容器 并把拼好的字符串(infoImgStr)寫進去document.getElementsByClassName('infoImg')[0].innerHTML = infoImgStr;};render();</script></body>
</html>
代碼詳解
HTML
<!-- 大底板 --><div class="aboutContent"><!-- 返回按鍵 --><div class="return"><img src="./img/jiantou.png" /><p>詳情頁</p></div><!-- 輪播圖 --><div class="banner"><div class="box"><!-- 圖1 --><img src="./img/iwtch.jpg" /><!-- 圖2 --><img src="./img/watch3.jpg" /><!-- 圖3 --><img src="./img/watch2.jpg" /><!-- 重復圖1 --><img src="./img/iwtch.jpg" /></div></div><!-- 價格橫條 --><!-- 詳情 --><div class="infoProduct"><!-- 名字 --><div id="infoProduct"></div><!-- 詳情 --><h3></h3><!-- 包郵 --><div></div><!-- 價格 --><p></p></div><!-- 分割線 --><div class="line"></div><!-- 圖片詳情 --><div class="infoImg"></div><div id="wide"></div><!-- 底部導航 --><div class="foot"><!-- 底部板子 --><div class="foot-center"><!-- 主頁 --><div class="chef"><div class="chef-logo"><img src="./img/home.png" alt="" /></div>主頁</div><!-- 分享 --><div class="chef"><div class="chef-logo"><img src="./img/about.png" alt="" /></div>分享</div><!-- 我的 --><div class="chef"><div class="chef-logo"><img src="./img/my.png" alt="" /></div>我的</div><!-- 購買 --><div class="buy"><div class="buy-logo"></div>立即購買</div></div></div></div>
CSS
* {margin: 0;padding: 0;}.return {width: 100%;/* height: 45px; */background-color: white;font-weight: 800;font-size: 19px;display: flex;/* justify-content: space-between; */align-items: center;position: fixed;z-index: 1;/* margin-top: -10px; */}.return p {/* margin-left: auto; *//* position: absolute; */margin-left: 36%;}.return img {width: 7%;}/* 定義輪播圖底板大小 */.banner {width: 100%;/* height: 700px; *//* margin-top: 6vh; *//* margin: auto; *//* border: 5px solid blue; *//* 將多余部分隱藏 */overflow: hidden;font-size: 0;}/* 規定容器里圖片規格 */.box img {width: 25%;height: 40vh;/* float: left; *//* display: inline-block; */}/* 包著圖片的容器大小 */.box {width: 400%;margin-top: 26px;/* height: 700px; *//* 動畫效果運用到每個圖片身上 *//* ---名字--持續時間--動畫播放次數=無限 */animation: donghua 13s infinite;}/* 當在 @keyframes 創建動畫,把它綁定到一個選擇器,否則動畫不會有任何效果。 */@keyframes donghua {/* 0% 是動畫的開始,100% 是動畫的完成。 */0% {margin-left: 0;}33.33% {/* 向左移負的1885px。因為上面規定的一張圖片的大小是1885px */margin-left: -100%;}66.66% {margin-left: -200%;}100% {margin-left: -300%;}}.priseContent {display: flex;justify-content: space-between;width: 100%;/* height: 60px; */background-color: #ff1e21;}.deja {/* display: inline-block; */}.price {margin-left: 10px;}.priceWord {/* display: inline-block; */background-color: #eb0003;padding: 6px;font-size: 17px;color: white;}.nowPrice {font-size: 25px;color: white;/* margin-left: 10px; */}.infoProduct {width: 96%;margin-left: 2%;margin-top: 5px;}#freeBuy {color: darkgray;}#infoProduct {color: #eb0003;font-weight: 400;}.infoProduct p {color: #eb0003;font-size: 20px;font-weight: 700;}.infoImg img {width: 100%;}.infoImg {/* height: 150vh; */width: 96%;margin-left: 2%;}.line {width: 100%;height: 5px;background-color: lightgray;margin-top: 5px;}.bottonContent {width: 100%;height: 70px;background-color: cadetblue;}/* /底部板子 */.foot-center {width: 100%;display: flex;position: fixed;bottom: 0;z-index: 1;justify-content: space-around;background-color: white;margin-top: 15%;height: 50px;}/* 小塊 */.chef {display: flex;flex-direction: column;text-align: center;width: 48px;height: 100%;font-size: 13px;font-weight: 100;margin-bottom: 5px;margin-top: 5px;}.foot-center img {width: 18px;height: 18px;}.kong {width: auto;height: 100px;}.buy {display: flex;align-items: center;justify-content: center;background-color: red;border-radius: 50px;padding-left: 70px;padding-right: 70px;color: white;margin-bottom: 5px;margin-top: 5px;/* margin-left: 50px; */}#wide {height: 10vh;}</style></head><body><!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport"content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><title></title><style>* {margin: 0;padding: 0;}.return {width: 100%;/* height: 45px; */background-color: white;font-weight: 800;font-size: 19px;display: flex;/* justify-content: space-between; */align-items: center;position: fixed;z-index: 1;/* margin-top: -10px; */}.return p {/* margin-left: auto; *//* position: absolute; */margin-left: 36%;}.return img {width: 7%;}/* 定義輪播圖底板大小 */.banner {width: 100%;/* height: 700px; *//* margin-top: 6vh; *//* margin: auto; *//* border: 5px solid blue; *//* 將多余部分隱藏 */overflow: hidden;font-size: 0;}/* 規定容器里圖片規格 */.box img {width: 25%;height: 40vh;/* float: left; *//* display: inline-block; */}/* 包著圖片的容器大小 */.box {width: 400%;margin-top: 26px;/* height: 700px; *//* 動畫效果運用到每個圖片身上 *//* ---名字--持續時間--動畫播放次數=無限 */animation: donghua 13s infinite;}/* 當在 @keyframes 創建動畫,把它綁定到一個選擇器,否則動畫不會有任何效果。 */@keyframes donghua {/* 0% 是動畫的開始,100% 是動畫的完成。 */0% {margin-left: 0;}33.33% {/* 向左移負的1885px。因為上面規定的一張圖片的大小是1885px */margin-left: -100%;}66.66% {margin-left: -200%;}100% {margin-left: -300%;}}.priseContent {display: flex;justify-content: space-between;width: 100%;/* height: 60px; */background-color: #ff1e21;}.deja {/* display: inline-block; */}.price {margin-left: 10px;}.priceWord {/* display: inline-block; */background-color: #eb0003;padding: 6px;font-size: 17px;color: white;}.nowPrice {font-size: 25px;color: white;/* margin-left: 10px; */}.infoProduct {width: 96%;margin-left: 2%;margin-top: 5px;}#freeBuy {color: darkgray;}#infoProduct {color: #eb0003;font-weight: 400;}.infoProduct p {color: #eb0003;font-size: 20px;font-weight: 700;}.infoImg img {width: 100%;}.infoImg {/* height: 150vh; */width: 96%;margin-left: 2%;}.line {width: 100%;height: 5px;background-color: lightgray;margin-top: 5px;}.bottonContent {width: 100%;height: 70px;background-color: cadetblue;}/* /底部板子 */.foot-center {width: 100%;display: flex;position: fixed;bottom: 0;z-index: 1;justify-content: space-around;background-color: white;margin-top: 15%;height: 50px;}/* 小塊 */.chef {display: flex;flex-direction: column;text-align: center;width: 48px;height: 100%;font-size: 13px;font-weight: 100;margin-bottom: 5px;margin-top: 5px;}.foot-center img {width: 18px;height: 18px;}.kong {width: auto;height: 100px;}.buy {display: flex;align-items: center;justify-content: center;background-color: red;border-radius: 50px;padding-left: 70px;padding-right: 70px;color: white;margin-bottom: 5px;margin-top: 5px;/* margin-left: 50px; */}#wide {height: 10vh;}
JS
js詳解
- 返回主頁事件
- 獲取元素:
document.getElementsByClassName('chef-logo')[0]
?選擇了頁面上第一個具有?chef - logo
?類名的元素,該元素通常用于代表主頁圖標。document.getElementsByClassName('return')[0]
?選擇了頁面上第一個具有?return
?類名的元素,這個元素可能是返回按鈕。
- 綁定點擊事件:
- 對于?
returnHome
?元素,當點擊時,window.location.href = './shop.html';
?會將頁面導航到?./shop.html
,實現返回主頁的功能。 - 同樣,對于?
returnLeft
?元素,點擊時也會導航到?./shop.html
。這意味著無論是點擊主頁圖標還是返回按鈕,都能回到?shop.html
?頁面。
- 對于?
- 獲取元素:
// 回主頁的點擊事件
let returnHome = document.getElementsByClassName('chef-logo')[0];
returnHome.onclick = function() {window.location.href = './shop.html';
}
// 回主頁的點擊事件
let returnLeft = document.getElementsByClassName('return')[0];
returnLeft.onclick = function() {window.location.href = './shop.html';
}
- 數據渲染部分
- 獲取本地存儲數據:
localStorage.getItem('details')
?從本地存儲中獲取鍵為?details
?的數據,該數據通常是在主頁存儲的商品詳情信息,以 JSON 字符串形式存儲。JSON.parse(localStorage.getItem('details'))
?將獲取到的 JSON 字符串解析為 JavaScript 對象,并賦值給?data
?變量。然后通過?console.log(data)
?將解析后的數據打印到控制臺,方便調試查看。
- 拼接并渲染商品詳情:
- 初始化一個空字符串?
str
,用于拼接商品詳情的 HTML 內容。 - 根據?
data
?對象中的屬性,將商品的名稱(data.name
)、詳情(data.info
)、包郵信息(data.about
)和價格(data.prise
)拼接成 HTML 片段。 document.getElementsByClassName('infoProduct')[0].innerHTML = str;
?獲取頁面上第一個具有?infoProduct
?類名的元素,并將拼接好的 HTML 內容設置為該元素的?innerHTML
,從而在頁面上渲染出商品詳情。
- 初始化一個空字符串?
- 獲取本地存儲數據:
//通過鍵名details在詳情頁獲取在主頁存的數據
//它的作用是將一個 JSON 格式的字符串解析為 JavaScript 對象
let data = JSON.parse(localStorage.getItem('details'));
console.log(data);//先聲明一個空字符串
let str = "";
//拼接字符串(根據json中的數據拼)
//如果想給他改樣式 需要在拼接字符串里命名 然后在用名字改樣式
str += `<div id="aboutContent"><div id="infoProduct">${data.name}</div><h3>${data.info}</h3><div id="freeBuy">${data.about}</div><p>${data.prise}</p>
`
//獲取商品的詳情部分,并把拼好的str寫進去
document.getElementsByClassName('infoProduct')[0].innerHTML = str;
- 輪播圖圖片渲染:
- 定義?
render
?函數用于渲染圖片。在函數內部,首先初始化一個空字符串?imgStr
,用于拼接輪播圖的圖片 HTML 代碼。 - 通過?
for
?循環遍歷?data.img
?數組,data.img
?數組應該包含了輪播圖所需的圖片路徑。每次循環將當前圖片路徑拼接到?imgStr
?中。 - 為了實現輪播圖首尾相連的循環效果,在循環結束后,又將第一張圖片路徑再次拼接到?
imgStr
?中。 document.getElementsByClassName('box')[0].innerHTML = imgStr;
?獲取頁面上第一個具有?box
?類名的元素(輪播圖容器),并將拼接好的圖片 HTML 代碼設置為該容器的?innerHTML
,從而實現輪播圖圖片的渲染。
- 定義?
- 詳情圖片渲染:
- 同樣初始化一個空字符串?
infoImgStr
,用于拼接商品詳情圖片的 HTML 代碼。 - 使用?
for
?循環遍歷?data.infoImg
?數組,data.infoImg
?數組包含商品詳情圖片的路徑。每次循環將當前圖片路徑拼接到?infoImgStr
?中。 document.getElementsByClassName('infoImg')[0].innerHTML = infoImgStr;
?獲取頁面上第一個具有?infoImg
?類名的元素(商品詳情圖片容器),并將拼接好的圖片 HTML 代碼設置為該容器的?innerHTML
,完成商品詳情圖片的渲染。
- 同樣初始化一個空字符串?
- 函數調用:最后調用?
render()
?函數,執行上述圖片渲染操作。
//渲染函數(為了渲染圖片的)
function render() {//=========================輪播圖的圖片拼接=========================//聲明一個空的字符串let imgStr = ""//使用for循環去遍歷img數組(json里的)for (let i = 0; i < data.img.length; i++) {// 每次循環都把當前的img下標往imgstr字符串里面拼imgStr += `<img src = "${data.img[i]}"/> `}// 首張圖片在展示時有重復顯示的效果imgStr += `<img src = "${data.img[0]}"/>`//獲取輪播圖的box容器 并把拼好的字符串(imgStr)寫進去document.getElementsByClassName('box')[0].innerHTML = imgStr;//=========================詳情的圖片拼接=========================//聲明一個空的字符串let infoImgStr = ""//使用for循環去遍歷img數組(json里的)for (let j = 0; j < data.infoImg.length; j++) {// 每次循環都把當前的img下標往infoImgStr字符串里面拼infoImgStr += `<img src = "${data.infoImg[j]}"/>`}//獲取詳情照片的infoImg容器 并把拼好的字符串(infoImgStr)寫進去document.getElementsByClassName('infoImg')[0].innerHTML = infoImgStr;
};
render();