商品列表及商品詳情展示

前言

本文將展示一段結合 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();

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67863.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67863.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67863.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[ VS Code 插件開發 ] 使用 Task ( 任務 ) 代替 createTerminal (終端) 來執行命令

VSCode 官方自己的插件就是這樣執行命令的. 使用體驗 比 默認的終端 好太多了. 重用終端, Shell 集成 , 按任意鍵關閉, 任務是否成功, 左側命令操作 (菜單中功能很多) 等 import * as vscode from vscode; // 執行的命令 let command_str "npm run dev" // 工作目…

大模型綜述一鏡到底(全文八萬字) ——《Large Language Models: A Survey》

論文鏈接&#xff1a;https://arxiv.org/abs/2402.06196 摘要&#xff1a;自2022年11月ChatGPT發布以來&#xff0c;大語言模型&#xff08;LLMs&#xff09;因其在廣泛的自然語言任務上的強大性能而備受關注。正如縮放定律所預測的那樣&#xff0c;大語言模型通過在大量文本數…

Python處理數據庫:MySQL與SQLite詳解

Python處理數據庫&#xff1a;MySQL與SQLite詳解 在數據處理和存儲方面&#xff0c;數據庫扮演著至關重要的角色。Python提供了多種與數據庫交互的方式&#xff0c;其中pymysql庫用于連接和操作MySQL數據庫&#xff0c;而SQLite則是一種輕量級的嵌入式數據庫&#xff0c;Pytho…

【C++】B2124 判斷字符串是否為回文

博客主頁&#xff1a; [小????????] 本文專欄: C 文章目錄 &#x1f4af;前言&#x1f4af;題目描述輸入格式&#xff1a;輸出格式&#xff1a;樣例&#xff1a; &#x1f4af;方法一&#xff1a;我的第一種做法思路代碼實現解析 &#x1f4af;方法二&#xff1a;我…

ubuntuCUDA安裝

系列文章目錄 移動硬盤制作Ubuntu系統盤 前言 根據前篇“移動硬盤制作Ubuntu系統盤”安裝系統后&#xff0c;還不能夠使用顯卡。 如果需要使用顯卡&#xff0c;還需要進行相關驅動的安裝&#xff08;如使用的為Nvidia顯卡&#xff0c;就需要安裝相關的Nvidia顯卡驅動&#xff…

Selenium 使用指南:從入門到精通

Selenium 使用指南&#xff1a;從入門到精通 Selenium 是一個用于自動化 Web 瀏覽器操作的強大工具&#xff0c;廣泛應用于自動化測試和 Web 數據爬取中。本文將帶你從入門到精通地掌握 Selenium&#xff0c;涵蓋其基本操作、常用用法以及一個完整的圖片爬取示例。 1. 環境配…

Sqoop導入MySQL中含有回車換行符的數據

個人博客地址&#xff1a;Sqoop導入MySQL中含有回車換行符的數據 MySQL中的數據如下圖&#xff1a; 檢查HDFS上的目標文件內容可以看出&#xff0c;回車換行符位置的數據被截斷了&#xff0c;導致數據列錯位。 Sqoop提供了配置參數&#xff0c;在導入時丟棄掉數據的分隔符&…

利用matlab尋找矩陣中最大值及其位置

目錄 一、問題描述1.1 max函數用法1.2 MATLAB中 : : :的作用1.3 ind2sub函數用法 二、實現方法2.1 方法一&#xff1a;max和find2.2 方法二&#xff1a;max和ind2sub2.3 方法對比 三、參考文獻 一、問題描述 matlab中求最大值可使用函數max&#xff0c;對于一維向量&#xff0…

PyTorch數據建模

回歸分析 import torch import numpy as np import pandas as pd from torch.utils.data import DataLoader,TensorDataset import time strat = time.perf_counter()

機試題——字符匹配

題目描述 給你一個字符串數組&#xff08;每個字符串均由小寫字母組成&#xff09;和一個字符規律&#xff08;由小寫字母和 . 和 * 組成&#xff09;&#xff0c;識別數組中哪些字符串可以匹配到字符規律上。 . 匹配任意單個字符。* 匹配零個或多個前面的那一個元素。 所謂…

《 C++ 點滴漫談: 二十五 》空指針,隱秘而危險的殺手:程序崩潰的真兇就在你眼前!

摘要 本博客全面解析了 C 中指針與空值的相關知識&#xff0c;從基礎概念到現代 C 的改進展開&#xff0c;涵蓋了空指針的定義、表示方式、使用場景以及常見注意事項。同時&#xff0c;深入探討了 nullptr 的引入及智能指針在提升代碼安全性和簡化內存管理方面的優勢。通過實際…

git push到遠程倉庫時無法推送大文件

一、錯誤 remote: Error: Deny by project hooks setting ‘default’: size of the file ‘scientific_calculator’, is 164 MiB, which has exceeded the limited size (100 MiB) in commit ‘4c91b7e3a04b8034892414d649860bf12416b614’. 二、原因 本地提交過大文件&am…

掌握API和控制點(從Java到JNI接口)_36 JNI開發與NDK 04

4、 *.so的入口函數&#xff1a;JNI_OnLoad() VM (virtual machine)的角色 Java代碼在VM上執行。在執行Java代碼的過程中&#xff0c;如果Java需要與本地代碼(*.so)溝通時&#xff0c; VM就會把*.so視為插件<Tn>而加載到VM里。然后讓Java函數呼叫到這插件<Tn>里的…

Windows圖形界面(GUI)-QT-C/C++ - QT Tab Widget

公開視頻 -> 鏈接點擊跳轉公開課程博客首頁 -> ???鏈接點擊跳轉博客主頁 目錄 一、概述 1.1 什么是 QTabWidget&#xff1f; 1.2 使用場景 二、常見樣式 2.1 選項卡式界面 2.2 動態添加和刪除選項卡 2.3 自定義選項卡標題和圖標 三、屬性設置 3.1 添加頁面&…

[MRCTF2020]Ez_bypass1(md5繞過)

[MRCTF2020]Ez_bypass1(md5繞過) ?? 這道題就是要繞過md5強類型比較&#xff0c;但是本身又不相等&#xff1a; md5無法處理數組&#xff0c;如果傳入的是數組進行md5加密&#xff0c;會直接放回NULL&#xff0c;兩個NuLL相比較會等于true&#xff1b; 所以?id[]1&gg…

90,【6】攻防世界 WEB Web_php_unserialize

進入靶場 進入靶場 <?php // 定義一個名為 Demo 的類 class Demo { // 定義一個私有屬性 $file&#xff0c;默認值為 index.phpprivate $file index.php;// 構造函數&#xff0c;當創建類的實例時會自動調用// 接收一個參數 $file&#xff0c;用于初始化對象的 $file 屬…

Jenkins安裝部署(以及常見報錯解決方案),jdk版本控制器sdkman

目錄 零、環境介紹 一、Jenkins安裝 1、插件安裝以及更換插件源 2、修改jenkins時區 二、sdkman安裝&#xff08;可選&#xff09; 1、sdkman常用方法 2、sdkman常用方法演示 2.1、查看可用的jdk 2.2、下載jdk并切換版本 三、jenkins報錯解決 1、下載sdkman后systemc…

大數據挖掘--兩個角度理解相似度計算理論

文章目錄 0 相似度計算可以轉換成什么問題1 集合相似度的應用1.1 集合相似度1.1文檔相似度1.2 協同過濾用戶-用戶協同過濾物品-物品協同過濾 1.2 文檔的shingling--將文檔表示成集合1.2.1 k-shingling1.2.2 基于停用詞的 shingling 1.3 最小哈希簽名1.4 局部敏感哈希算法&#…

關于貪心學習的文筆記錄

貪心&#xff0c;顧名思義就是越貪越好&#xff0c;越多越有易&#xff0c;他給我的感覺是&#xff0c;通常是求最大或最小問題&#xff0c;相比于動態規劃貪心讓人更加琢磨不透&#xff0c;不易看出方法&#xff0c;為此在這記錄我所見過的題型和思維方法&#xff0c;以便回頭…

c語言練習題【數據類型、遞歸、雙向鏈表快速排序】

練習1&#xff1a;數據類型 請寫出以下幾個數據的數據類型 整數 a a 的地址 存放a的數組 b 存放a的地址的數組 b的地址 c的地址 指向 printf 函數的指針 d 存放 d的數組 整數 a 的類型 數據類型是 int a 的地址 數據類型是 int*&#xff08;指向 int 類型的指針&#xff09; …