分析器错误消息: 服务器标记的格式不正确。 源错误: 行 31: <div class="d-grid"> 行 32: <lable id="ErrMsg" runat="server"></lable> 行 33: <asp:Button ID="SaveBtn"runat="server"Text="保存"class="btn btn-dark btn-block" /> 行
时间: 2023-12-05 17:29:05 浏览: 156
根据错误消息分析,第 31 行代码中的 `<div>` 标签格式可能存在问题。可能是标签的闭合不正确或者标签内部缺少必要的属性等。建议检查该行代码,并且检查前面的代码是否有未闭合的标签。另外,第 32 行代码中的 `lable` 标签应该是 `label` 标签的拼写错误,需要进行修改。最后,第 33 行代码中的 `ID` 属性应该改为 `Id`。修改后,代码应该如下所示:
```
<div class="d-grid">
<label id="ErrMsg" runat="server"></label>
<asp:Button Id="SaveBtn" runat="server" Text="保存" class="btn btn-dark btn-block" />
</div>
```
相关问题
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模块导航系统</title> <style> /* 全局样式 */ * { box-sizing: border-box; } /* 导航栏样式 - 优化 */ .navbar { background-color: transparent; position: relative; padding: 15px 0; margin-bottom: 30px; } .nav-container { width: 90%; max-width: 1200px; margin: 0 auto; display: flex; justify-content: center; /* 居中导航 */ } .nav-links { display: flex; list-style: none; gap: 15px; /* 按钮间距 */ } .nav-item { margin: 0 5px; } .nav-link { text-decoration: none; color: #0566a8; /* 蓝色文字 */ background: white; /* 白色背景 */ font-weight: 500; padding: 10px 25px; border-radius: 30px; /* 圆角 */ border: 2px solid #0566a8; /* 蓝色边框 */ transition: all 0.3s ease; display: inline-block; text-align: center; min-width: 120px; } .nav-link:hover { background: rgba(5, 102, 168, 0.1); } .nav-link.active { background: #0566a8; /* 蓝色背景 */ color: white; /* 白色文字 */ font-weight: 600; } /* 模块容器样式 */ .module-container { width: 90%; max-width: 1200px; margin: 40px auto; position: relative; min-height: 600px; overflow: hidden; } .module { position: absolute; top: 0; left: 0; width: 100%; opacity: 0; visibility: hidden; transform: translateY(20px); transition: opacity 0.6s ease, transform 0.6s ease, visibility 0.6s; z-index: 1; } .module.active { opacity: 1; visibility: visible; transform: translateY(0); z-index: 2; } /* 模块特定样式 */ .module-content { background-color: #fff; border-radius: 12px; box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05); overflow: hidden; margin-bottom: 30px; } /* 响应式设计 */ @media (max-width: 768px) { .nav-container { flex-direction: column; align-items: flex-start; } .nav-links { margin-top: 15px; flex-wrap: wrap; } .nav-item { margin: 5px 15px 5px 0; } .module-container { margin: 20px auto; } } /* 模块1样式 */ #module1 .minimal-process { max-width: 100%; margin: 0; } /* 模块2样式 */ #module2 .fp-carousel-module { max-width: 100%; margin: 0; } /* 模块3样式 */ #module3 .luxemg-container { max-width: 100%; padding: 20px; } /* 模块4样式 */ #module4 .carousel-container { max-width: 100%; margin: 0; } </style> </head> <body> <!-- 导航栏 --> <nav class="navbar"> <div class="nav-container"> <ul class="nav-links"> <li class="nav-item"> <a href="#" class="nav-link active" data-target="module1">服务流程</a> </li> <li class="nav-item"> <a href="#" class="nav-link" data-target="module2">3D轮播</a> </li> <li class="nav-item"> <a href="#" class="nav-link" data-target="module3">材料展示</a> </li> <li class="nav-item"> <a href="#" class="nav-link" data-target="module4">图片轮播</a> </li> </ul> </div> </nav> <!-- 模块容器 --> <div class="module-container"> <!-- 模块1:服务流程 --> <div id="module1" class="module active"> <div class="module-content"> <!-- 代码1的内容 --> <div class="minimal-process"> <div class="process-container"> <!-- 步骤 1 --> <div class="process-step"> <div class="step-icon"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/youxiang.png" alt="咨询"> </div> <div class="step-content"> <span class="step-number">1</span> <h3 class="step-title">Demand consultation</h3> <p class="step-desc">The customer sends a contact email to get the consultation.</p> </div> </div> <!-- 步骤 2 --> <div class="process-step"> <div class="step-icon"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/kefu.png" alt="设计"> </div> <div class="step-content"> <span class="step-number">2</span> <h3 class="step-title">Solution Design</h3> <p class="step-desc">The business manager conducts content docking with the customer.</p> </div> </div> <!-- 步骤 3 --> <div class="process-step"> <div class="step-icon"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/emptybox.png" alt="实施"> </div> <div class="step-content"> <span class="step-number">3</span> <h3 class="step-title">Professional implementation</h3> <p class="step-desc">We make a samptle according to the customer's requirements and confirm the details.</p> </div> </div> <!-- 步骤 4 --> <div class="process-step"> <div class="step-icon"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/woshou.png" alt="交付"> </div> <div class="step-content"> <span class="step-number">4</span> <h3 class="step-title">Successfully placed order</h3> <p class="step-desc">After the customer's confirmation,the customer pays the deposit and places the order.</p> </div> </div> </div> </div> </div> </div> <!-- 模块2:3D轮播 --> <div id="module2" class="module"> <div class="module-content"> <!-- 代码2的内容 --> <div class="fp-carousel-module"> <div class="fp-carousel-container"> <div class="fp-carousel-item fp-active" data-index="0"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-14_59_30_compressed.png" alt="Printing"> <div class="fp-description">Printing:Transfer your design onto paper or board using offset, digital or flexo presses.</div> </div> <div class="fp-carousel-item fp-next" data-index="1"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_02_51_compressed.png" alt="Surface Finishing"> <div class="fp-description">Surface Finishing:Enhance and protect the print by adding coatings or varnishes (e.g. UV, matte or gloss).</div> </div> <div class="fp-carousel-item fp-next-far" data-index="2"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_05_48_compressed.png"> <div class="fp-description">Lamination (Mounting):Bond the printed sheet to a sturdier substrate or apply a clear film for extra durability.</div> </div> <div class="fp-carousel-item fp-prev" data-index="3"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_11_40_compressed.png" alt="Die-Cutting"> <div class="fp-description">Die-Cutting:Use a custom metal die to cut out shapes, create windows or trim the edges precisely.</div> </div> <div class="fp-carousel-item fp-prev-far" data-index="4"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_21_01_compressed.png"> <div class="fp-description">Gluing & Assembly:Fold and glue the die-cut pieces together to form boxes, folders or other finished items.</div> </div> <div class="fp-carousel-item fp-prev-far" data-index="5"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_24_28_compressed.png" alt="Packing & Shipping"> <div class="fp-description">Packing & Shipping:Stack, bundle or carton the completed products, then palletize and dispatch them to the client.</div> </div> <div class="fp-nav-btn fp-prev-btn"> <div class="fp-arrow">❮</div> </div> <div class="fp-nav-btn fp-next-btn"> <div class="fp-arrow">❯</div> </div> </div> </div> </div> </div> <!-- 模块3:材料展示 --> <div id="module3" class="module"> <div class="module-content"> <!-- 代码3的内容 --> <div class="luxemg-container"> <!-- Paper board 部分 --> <h2 class="luxemg-section-title">Paper board</h2> <div class="luxemg-grid"> <!-- SBS C1S --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_59_47_compressed.png" alt="SBS C1S" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">SBS C1S</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-sbs-c1s">VIEW MORE</button> </div> </div> <!-- SBS C2S --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_45_42_compressed.png" alt="SBS C2S" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">SBS C2S</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-sbs-c2s">VIEW MORE</button> </div> </div> <!-- CCNB --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_44_52_compressed.png" alt="CCNB" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">CCNB</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-ccnb">VIEW MORE</button> </div> </div> <!-- UUK --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=UUK" alt="UUK" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">UUK</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-uuk">VIEW MORE</button> </div> </div> <!-- Metallic --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=Metallic" alt="Metallic" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">Metallic</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-metallic">VIEW MORE</button> </div> </div> </div> <!-- Corrugated 部分 --> <h2 class="luxemg-section-title">Corrugated</h2> <!-- single wall部分 --> <h3 class="luxemg-subsection-title">single wall</h3> <div class="luxemg-grid"> <!-- A Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=A+Flute" alt="A Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">A Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-a-flute">VIEW MORE</button> </div> </div> <!-- C Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=C+Flute" alt="C Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">C Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-c-flute">VIEW MORE</button> </div> </div> <!-- B Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=B+Flute" alt="B Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">B Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-b-flute">VIEW MORE</button> </div> </div> <!-- E Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=E+Flute" alt="E Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">E Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-e-flute">VIEW MORE</button> </div> </div> <!-- F Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=F+Flute" alt="F Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">F Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-f-flute">VIEW MORE</button> </div> </div> </div> <!-- double wall部分 --> <h3 class="luxemg-subsection-title">double wall</h3> <div class="luxemg-grid"> <!-- B/C Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=B/C+Flute" alt="B/C Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">B/C Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-bc-flute">VIEW MORE</button> </div> </div> <!-- E/C Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=E/C+Flute" alt="E/C Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">E/C Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-ec-flute">VIEW MORE</button> </div> </div> <!-- E/B Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=E/B+Flute" alt="E/B Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">E/B Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-eb-flute">VIEW MORE</button> </div> </div> <!-- F/E Flute --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=F/E+Flute" alt="F/E Flute" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">F/E Flute</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-fe-flute">VIEW MORE</button> </div> </div> </div> <!-- Print 部分 --> <h2 class="luxemg-section-title">Print</h2> <div class="luxemg-grid"> <!-- CMYK --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=CMYK" alt="CMYK" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">CMYK</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-cmyk">VIEW MORE</button> </div> </div> <!-- Pantone --> <div class="luxemg-card"> <div class="luxemg-card-image"> <img src="https://via.placeholder.com/300x240?text=Pantone" alt="Pantone" class="luxemg-card-img"> </div> <div class="luxemg-card-content"> <h3 class="luxemg-card-title">Pantone</h3> <button class="luxemg-detail-btn" data-luxemg-modal="modal-pantone">VIEW MORE</button> </div> </div> </div> </div> </div> </div> <!-- 模块4:图片轮播 --> <div id="module4" class="module"> <div class="module-content"> <!-- 代码4的内容 --> <div class="carousel-container"> <!-- 轮播轨道 --> <div class="carousel"> <!-- 轮播项1 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Lamination-Gloss_Matte1_compressed.png" alt="Lamination (Gloss/Matte)"> <div class="image-info"> <h3>Lamination (Gloss/Matte)</h3> <p>– Applying a thin plastic film over the printed sheet to enhance scratch resistance, moisture protection and overall durability. Gloss lamination yields a shiny surface, while matte lamination gives a low-sheen, soft-touch effect.</p> </div> </div> <!-- 轮播项2 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/UV-Coating-Spot_Overall_compressed.png" alt="UV Coating (Spot/Overall)"> <div class="image-info"> <h3>UV Coating (Spot/Overall)</h3> <p>– Spreading a liquid UV-curable varnish onto either selected areas (spot UV) or the entire sheet, then instantly curing it under UV light. Creates high gloss and tactile contrast.</p> </div> </div> <!-- 轮播项3 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Hot-Foil-Stamping_compressed.png" alt="Hot Foil Stamping"> <div class="image-info"> <h3>Hot Foil Stamping</h3> <p>– Transferring metallic or pigmented foil onto specific areas of the print using heat and pressure. Delivers a premium metallic sheen (gold, silver, colored foils) for logos or decorative accents.</p> </div> </div> <!-- 轮播项4 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Embossing-_-Debossing1_compressed.png" alt="Embossing / Debossing"> <div class="image-info"> <h3>Embossing / Debossing</h3> <p>– Pressing the paper between male and female dies to create a raised (emboss) or recessed (deboss) 3D relief. Adds tactile interest and a sense of depth.</p> </div> </div> <!-- 轮播项5 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Die-Cutting_compressed.png" alt="Die-Cutting"> <div class="image-info"> <h3>Die-Cutting</h3> <p>– Using a custom-made metal die to cut the printed sheet into precise shapes or create windows/slots. Essential for producing custom box shapes, hang-tabs, or intricate cut-outs.</p> </div> </div> <!-- 轮播项6 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Creasing-Folding-Crease_compressed.png" alt="Creasing (Folding Crease)"> <div class="image-info"> <h3>Creasing (Folding Crease)</h3> <p>– Impressing a crease line on the sheet to facilitate clean, accurate folds without cracking the coating or ink. Critical for boxes, folders, and other folded structures.</p> </div> </div> <!-- 轮播项7 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Spot-UV-Emboss-Combination_compressed.png" alt="Spot UV + Emboss Combination"> <div class="image-info"> <h3>Spot UV + Emboss Combination</h3> <p>– First applying spot UV coating, then embossing the same area to create a shiny, raised element. Enhances both visual shine and tactile relief simultaneously.</p> </div> </div> <!-- 轮播项8 --> <div class="carousel-item"> <img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Laser-Finishing-Holographic-Etch-Combination_compressed.png" alt="Holographic Foil Stamping"> <div class="image-info"> <h3>Holographic Foil Stamping</h3> <p>— Laser-etch microscopic holographic patterns onto foil, then heat- or UV-cure to lock in vibrant, angle-shifting colors and subtle texture for a premium anti-counterfeiting finish.</p> </div> </div> </div> <!-- 控制按钮 --> <div class="carousel-controls"> <button class="control-btn" id="prevBtn">Previous</button> <button class="control-btn" id="nextBtn">next</button> <button class="control-btn" id="autoBtn">暂停轮播</button> </div> <!-- 指示器 --> <div class="indicator"> <div class="indicator-dot active" data-index="0"></div> <div class="indicator-dot" data-index="1"></div> <div class="indicator-dot" data-index="2"></div> <div class="indicator-dot" data-index="3"></div> </div> </div> </div> </div> </div> <!-- 模态框容器 --> <div id="luxemg-modal-container" class="luxemg-modal-container"> <div class="luxemg-modal-wrapper"> <div class="luxemg-modal-content"> <div class="luxemg-modal-header"> <h3 id="luxemg-modal-title" class="luxemg-modal-title">Material Details</h3> <button id="luxemg-close-modal" class="luxemg-close-btn">×</button> </div> <div class="luxemg-modal-body"> <div class="luxemg-modal-image-container"> <img id="luxemg-modal-image" class="luxemg-modal-img" src="" alt="Material"> </div> <div class="luxemg-modal-description"> <div id="luxemg-modal-description" class="luxemg-modal-desc"></div> </div> </div> </div> </div> </div> <!-- JavaScript --> <script> // 导航切换功能 document.addEventListener('DOMContentLoaded', function() { // 导航切换 const navLinks = document.querySelectorAll('.nav-link'); const modules = document.querySelectorAll('.module'); navLinks.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); // 获取目标模块ID const targetId = this.getAttribute('data-target'); // 更新导航状态 navLinks.forEach(l => l.classList.remove('active')); this.classList.add('active'); // 切换模块 modules.forEach(module => { module.classList.remove('active'); }); document.getElementById(targetId).classList.add('active'); }); }); // 初始化模块2的轮播功能 initCarousel(document.querySelector('#module2 .fp-carousel-module')); // 初始化模块3的模态框功能 initLuxemgGallery(); // 初始化模块4的轮播功能 initModule4Carousel(); }); // 模块2的轮播功能 function initCarousel(module) { const container = module.querySelector('.fp-carousel-container'); const items = Array.from(module.querySelectorAll('.fp-carousel-item')); const prevBtn = module.querySelector('.fp-prev-btn'); const nextBtn = module.querySelector('.fp-next-btn'); let currentIndex = 0; let isAnimating = false; // 初始化位置 updatePositions(); // 事件绑定函数 const bindEvents = function() { // 图片点击事件 items.forEach(item => { item.addEventListener('click', function(e) { e.stopPropagation(); if (isAnimating) return; isAnimating = true; if (this.classList.contains('fp-next') || this.classList.contains('fp-next-far')) { navigate(1); } else if (this.classList.contains('fp-prev') || this.classList.contains('fp-prev-far')) { navigate(-1); } // 动画结束后重置标志 setTimeout(() => isAnimating = false, 700); }); }); // 容器区域点击 container.addEventListener('click', function(e) { if (isAnimating) return; isAnimating = true; const rect = container.getBoundingClientRect(); const clickX = e.clientX - rect.left; if (clickX > rect.width * 3/4) { navigate(1); } else if (clickX < rect.width * 1/4) { navigate(-1); } setTimeout(() => isAnimating = false, 700); }); // 导航按钮 prevBtn.addEventListener('click', function(e) { e.stopPropagation(); if (isAnimating) return; isAnimating = true; navigate(-1); setTimeout(() => isAnimating = false, 700); }); nextBtn.addEventListener('click', function(e) { e.stopPropagation(); if (isAnimating) return; isAnimating = true; navigate(1); setTimeout(() => isAnimating = false, 700); }); // 键盘导航 document.addEventListener('keydown', function(e) { if (isAnimating) return; isAnimating = true; if (e.key === 'ArrowLeft') { navigate(-1); } else if (e.key === 'ArrowRight') { navigate(1); } setTimeout(() => isAnimating = false, 700); }); // 响应式调整 window.addEventListener('resize', function() { updatePositions(); }); }; // 导航函数 function navigate(direction) { currentIndex = (currentIndex + direction + items.length) % items.length; updatePositions(); } // 更新位置 function updatePositions() { items.forEach((item, index) => { item.classList.remove('fp-active', 'fp-prev', 'fp-next', 'fp-prev-far', 'fp-next-far', 'fp-hidden'); const position = (index - currentIndex + items.length) % items.length; if (position === 0) { item.classList.add('fp-active'); } else if (position === 1) { item.classList.add('fp-next'); } else if (position === 2) { item.classList.add('fp-next-far'); } else if (position === items.length - 1) { item.classList.add('fp-prev'); } else if (position === items.length - 2) { item.classList.add('fp-prev-far'); } else { item.classList.add('fp-hidden'); } }); } // 初始化事件绑定 bindEvents(); } // 模块3的模态框功能 function initLuxemgGallery() { // 材料详情数据 const luxemgMaterialDetails = { // Paper board "modal-sbs-c1s": { title: "SBS C1S", image: "https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_59_47_compressed.png", description: "<p>SBS C1S(Solid Bleached Sulfate – Coated One Side) is a premium-grade paperboard made from 100% virgin bleached wood pulp. It is coated on one side to provide an exceptionally smooth and white printing surface, while the reverse side remains uncoated for functional versatility.</p><p>Key Features:<br>- Bright White Appearance: Produced from fully bleached fibers for a clean, uniform, and high-end look.<br>- Coated One Side (C1S): One side has a clay coating for excellent printability; the reverse side is uncoated for better glue adhesion or writing.<br>- Excellent Print Surface: Ideal for offset, digital, and specialty printing methods; supports vibrant color reproduction and fine detail.<br>- High Stiffness and Strength: Offers good structural integrity, making it suitable for rigid packaging and die-cut designs.<br>- Environmentally Friendly: Recyclable, biodegradable, and available with FSC certification upon request.</p><p>Main Advantages:<br>✅ Preferred choice for premium packaging (cosmetics, personal care, high-end retail)<br>✅ Superior surface for specialty finishes like foil stamping, embossing, and spot UV<br>✅ Balanced combination of print quality and converting performance<br>✅ Consistent white core and surface enhance the perceived value of the final product<br>✅ Compatible with folding, scoring, gluing, and other post-press operations</p>" }, // ... 其他材料详情 }; // DOM元素引用 const luxemgModalContainer = document.getElementById('luxemg-modal-container'); const luxemgModalTitle = document.getElementById('luxemg-modal-title'); const luxemgModalImage = document.getElementById('luxemg-modal-image'); const luxemgModalDescription = document.getElementById('luxemg-modal-description'); const luxemgCloseModal = document.getElementById('luxemg-close-modal'); // 打开模态框函数 function openLuxemgModal(modalId) { const material = luxemgMaterialDetails[modalId]; const modalContent = luxemgModalContainer.querySelector('.luxemg-modal-content'); if (!material) { console.error("Material details not found for:", modalId); return; } // 填充模态框内容 luxemgModalTitle.textContent = material.title; luxemgModalImage.src = material.image; luxemgModalImage.alt = material.title; luxemgModalDescription.innerHTML = material.description; // 显示模态框 luxemgModalContainer.style.display = 'block'; // 强制重绘确保动画执行 void luxemgModalContainer.offsetWidth; // 应用显示动画 setTimeout(() => { luxemgModalContainer.style.opacity = '1'; modalContent.style.transform = 'scale(1)'; modalContent.style.opacity = '1'; }, 10); // 禁止背景滚动 document.body.style.overflow = 'hidden'; } // 关闭模态框函数 function closeLuxemgModal() { const modalContent = luxemgModalContainer.querySelector('.luxemg-modal-content'); luxemgModalContainer.style.opacity = '0'; modalContent.style.transform = 'scale(0.95)'; modalContent.style.opacity = '0'; setTimeout(() => { luxemgModalContainer.style.display = 'none'; document.body.style.overflow = ''; }, 300); } // 事件绑定函数 luxemgCloseModal.addEventListener('click', closeLuxemgModal); luxemgModalContainer.addEventListener('click', function(e) { if (e.target === this) closeLuxemgModal(); }); document.addEventListener('keydown', function(e) { if (e.key === 'Escape') closeLuxemgModal(); }); document.addEventListener('click', function(e) { if (e.target.classList.contains('luxemg-detail-btn')) { const modalId = e.target.getAttribute('data-luxemg-modal'); openLuxemgModal(modalId); } }); } // 模块4的轮播功能 function initModule4Carousel() { // 获取DOM元素 const carousel = document.querySelector('#module4 .carousel'); const items = document.querySelectorAll('#module4 .carousel-item'); const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); const autoBtn = document.getElementById('autoBtn'); const dots = document.querySelectorAll('#module4 .indicator-dot'); // 初始化变量 let currentIndex = 0; let itemsPerView = calculateItemsPerView(); let autoPlayInterval; let isAutoPlay = true; // 计算当前视图显示的项目数 function calculateItemsPerView() { const width = window.innerWidth; if (width <= 500) return 1; if (width <= 700) return 2; if (width <= 900) return 3; return 4; } // 更新轮播位置 function updateCarousel() { // 计算每个项目的宽度百分比 const itemWidth = 100 / itemsPerView; // 计算偏移量 const offset = -currentIndex * itemWidth; // 应用转换效果 carousel.style.transform = `translateX(${offset}%)`; // 更新指示点状态 dots.forEach((dot, index) => { dot.classList.toggle('active', index === currentIndex); }); } // 下一张 function nextSlide() { // 计算最大索引 const maxIndex = items.length - itemsPerView; // 更新当前索引(循环) currentIndex = currentIndex >= maxIndex ? 0 : currentIndex + 1; updateCarousel(); } // 上一张 function prevSlide() { // 计算最大索引 const maxIndex = items.length - itemsPerView; // 更新当前索引(循环) currentIndex = currentIndex <= 0 ? maxIndex : currentIndex - 1; updateCarousel(); } // 自动轮播 function startAutoPlay() { if (isAutoPlay) { // 设置轮播间隔 autoPlayInterval = setInterval(nextSlide, 3000); // 更新按钮文本 autoBtn.textContent = 'stop'; } } // 停止自动轮播 function stopAutoPlay() { // 清除轮播间隔 clearInterval(autoPlayInterval); // 更新按钮文本 autoBtn.textContent = 'start'; } // 切换自动轮播状态 function toggleAutoPlay() { // 反转自动播放状态 isAutoPlay = !isAutoPlay; if (isAutoPlay) { startAutoPlay(); } else { stopAutoPlay(); } } // 初始化轮播 function init() { // 计算每屏显示数量 itemsPerView = calculateItemsPerView(); // 更新轮播位置 updateCarousel(); // 开始自动播放 startAutoPlay(); } // 事件监听器 nextBtn.addEventListener('click', () => { nextSlide(); // 如果自动播放已暂停,则停止轮播 if (!isAutoPlay) stopAutoPlay(); }); prevBtn.addEventListener('click', () => { prevSlide(); // 如果自动播放已暂停,则停止轮播 if (!isAutoPlay) stopAutoPlay(); }); autoBtn.addEventListener('click', toggleAutoPlay); // 为每个指示点添加点击事件 dots.forEach(dot => { dot.addEventListener('click', () => { // 获取并设置当前索引 currentIndex = parseInt(dot.getAttribute('data-index')); updateCarousel(); // 如果自动播放已暂停,则停止轮播 if (!isAutoPlay) stopAutoPlay(); }); }); // 窗口大小变化时重新计算 window.addEventListener('resize', () => { // 重新计算每屏显示数量 itemsPerView = calculateItemsPerView(); // 更新轮播位置 updateCarousel(); }); // 初始化轮播 init(); } </script> </body> </html> 将这个代码中的按钮都改成#0566a8色的字和微微圆角边框,代码四下方的原点增加到8个
<think>我们注意到原代码中已经有一些样式,但需要修改按钮的样式,将按钮文字颜色改为#0566a8,并添加微微圆角的边框。同时,模块4(图片轮播)下方的指示点(indicator dots)目前只有4个,但轮播项有8个,需要增加到8个。修改点:1.导航栏的按钮(.nav-link)已经符合要求(蓝色文字和圆角边框),但其他按钮(如模块3中的“VIEW MORE”按钮,模块4中的控制按钮)也需要修改。2.模块3中的“VIEW MORE”按钮:需要修改文字颜色为#0566a8,并添加圆角边框。3.模块4中的控制按钮(Previous,next,暂停轮播)需要修改文字颜色为#0566a8,并添加圆角边框。4.模块4的指示点(indicatordots)需要从4个增加到8个。步骤:1.为模块3的“VIEW MORE”按钮添加样式,使其文字颜色为#0566a8,背景白色,圆角边框,并设置圆角大小(例如border-radius:4px,或者按需求调整)。2.为模块4的控制按钮添加样式,同样文字颜色#0566a8,背景白色,圆角边框。3.在模块4的指示点部分,将指示点数量增加到8个(每个轮播项对应一个)。注意:原代码中模块4的指示点部分只有4个div,我们需要根据轮播项的数量(8个)来添加8个指示点。具体修改:一、模块3的按钮样式修改:在CSS中添加或修改以下样式:```css.luxemg-detail-btn{color:#0566a8;background:white;border:2pxsolid #0566a8;border-radius:4px; /*微微圆角*/padding:8px16px;font-weight:500;cursor:pointer;transition: all0.3sease;}.luxemg-detail-btn:hover {background: rgba(5,102,168,0.1);}```二、模块4的控制按钮样式修改:在CSS中添加或修改以下样式:```css.control-btn {color: #0566a8;background:white;border:2pxsolid #0566a8;border-radius:4px; /*微微圆角*/padding:8px16px;margin:05px;font-weight:500;cursor:pointer;transition: all0.3sease;}.control-btn:hover {background: rgba(5,102,168,0.1);}```三、模块4的指示点数量修改:在模块4的HTML部分,找到指示点容器(class为indicator),将其中的指示点数量增加到8个,每个对应一个轮播项(索引0到7)。修改前(只有4个):```html<divclass="indicator"><divclass="indicator-dotactive"data-index="0"></div><divclass="indicator-dot" data-index="1"></div><div class="indicator-dot"data-index="2"></div><divclass="indicator-dot" data-index="3"></div></div>```修改后(8个):```html<div class="indicator"><div class="indicator-dot active" data-index="0"></div><div class="indicator-dot"data-index="1"></div><divclass="indicator-dot" data-index="2"></div><div class="indicator-dot"data-index="3"></div><divclass="indicator-dot" data-index="4"></div><div class="indicator-dot"data-index="5"></div><divclass="indicator-dot" data-index="6"></div><div class="indicator-dot"data-index="7"></div></div>```注意:由于轮播项有8个,但每屏显示的数量可能为1到4个(根据屏幕宽度),所以指示点应该对应轮播项,而不是每屏。因此,我们添加8个指示点,每个对应一个轮播项。在轮播逻辑中,当前索引指示点高亮。另外,在模块4的轮播初始化函数(initModule4Carousel)中,我们使用currentIndex来更新指示点状态,但要注意,由于每屏显示多个项目,所以指示点应该表示当前显示的第一个项目的索引。因此,我们只需要一个指示点高亮,即当前轮播的第一个项目的索引。原逻辑中,dots的点击事件已经设置了currentIndex,所以不需要修改。但是,原代码中指示点的数量是固定的,现在改为8个,所以需要修改HTML。由于原代码中模块4的轮播项有8个(class为carousel-item的div有8个),所以我们将指示点增加到8个。最后,在CSS中调整指示点的样式,确保它们在一行中显示且不换行,可能需要添加flex-wrap:nowrap和overflow-x:auto(如果需要横向滚动的话),但通常8个点在一行中可能在小屏幕上会超出,所以可以考虑让指示点容器可以横向滚动,或者将指示点缩小并调整间距。这里我们选择调整指示点容器,使其可以横向滚动(如果超出容器宽度):```css.indicator {display: flex;justify-content: center;flex-wrap: nowrap;overflow-x:auto;padding:10px0;}```但考虑到8个点不会太长,我们可以先这样处理。现在,我们将修改后的完整代码整合。注意:由于原代码较长,我们只修改了部分样式和HTML结构。请将修改后的代码整合到原文件中。由于代码量很大,这里只展示修改的部分,但为了清晰,我将提供完整的修改后的代码。但请注意,由于问题要求修改按钮样式和指示点数量,我们只修改了上述部分。其他部分保持不变。由于代码太长,我将提供修改后的完整代码,但只重点展示修改的部分。</think>我已经分析了您的需求,需要将页面中的按钮统一修改为蓝色文字(#0566a8)并添加圆角边框,同时将模块4的指示点增加到8个。以下是修改后的完整代码:
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模块导航系统</title>
<style>
/* 全局样式 */
* {
box-sizing: border-box;
}
/* 导航栏样式 - 优化 */
.navbar {
background-color: transparent;
position: relative;
padding: 15px 0;
margin-bottom: 30px;
}
.nav-container {
width: 90%;
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: center; /* 居中导航 */
}
.nav-links {
display: flex;
list-style: none;
gap: 15px; /* 按钮间距 */
}
.nav-item {
margin: 0 5px;
}
.nav-link {
text-decoration: none;
color: #0566a8; /* 蓝色文字 */
background: white; /* 白色背景 */
font-weight: 500;
padding: 10px 25px;
border-radius: 30px; /* 圆角 */
border: 2px solid #0566a8; /* 蓝色边框 */
transition: all 0.3s ease;
display: inline-block;
text-align: center;
min-width: 120px;
}
.nav-link:hover {
background: rgba(5, 102, 168, 0.1);
}
.nav-link.active {
background: #0566a8; /* 蓝色背景 */
color: white; /* 白色文字 */
font-weight: 600;
}
/* 模块容器样式 */
.module-container {
width: 90%;
max-width: 1200px;
margin: 40px auto;
position: relative;
min-height: 600px;
overflow: hidden;
}
.module {
position: absolute;
top: 0;
left: 0;
width: 100%;
opacity: 0;
visibility: hidden;
transform: translateY(20px);
transition: opacity 0.6s ease, transform 0.6s ease, visibility 0.6s;
z-index: 1;
}
.module.active {
opacity: 1;
visibility: visible;
transform: translateY(0);
z-index: 2;
}
/* 模块特定样式 */
.module-content {
background-color: #fff;
border-radius: 12px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
overflow: hidden;
margin-bottom: 30px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.nav-container {
flex-direction: column;
align-items: flex-start;
}
.nav-links {
margin-top: 15px;
flex-wrap: wrap;
}
.nav-item {
margin: 5px 15px 5px 0;
}
.module-container {
margin: 20px auto;
}
}
/* 模块1样式 */
#module1 .minimal-process {
max-width: 100%;
margin: 0;
}
/* 模块2样式 */
#module2 .fp-carousel-module {
max-width: 100%;
margin: 0;
}
/* 模块3样式 */
#module3 .luxemg-container {
max-width: 100%;
padding: 20px;
}
/* 模块4样式 */
#module4 .carousel-container {
max-width: 100%;
margin: 0;
}
/* 按钮样式统一修改 */
.luxemg-detail-btn,
.control-btn {
color: #0566a8; /* 蓝色文字 */
background: white; /* 白色背景 */
font-weight: 500;
padding: 8px 16px;
border-radius: 4px; /* 微微圆角 */
border: 2px solid #0566a8; /* 蓝色边框 */
transition: all 0.3s ease;
cursor: pointer;
}
.luxemg-detail-btn:hover,
.control-btn:hover {
background: rgba(5, 102, 168, 0.1);
}
/* 指示点容器样式调整 */
.indicator {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 8px;
padding: 10px 0;
}
</style>
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar">
<div class="nav-container">
<ul class="nav-links">
<li class="nav-item">
<a href="#" class="nav-link active" data-target="module1">服务流程</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" data-target="module2">3D轮播</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" data-target="module3">材料展示</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" data-target="module4">图片轮播</a>
</li>
</ul>
</div>
</nav>
<!-- 模块容器 -->
<div class="module-container">
<!-- 模块1:服务流程 -->
<div id="module1" class="module active">
<div class="module-content">
<!-- 代码1的内容 -->
<div class="minimal-process">
<div class="process-container">
<!-- 步骤 1 -->
<div class="process-step">
<div class="step-icon">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/youxiang.png" alt="咨询">
</div>
<div class="step-content">
<span class="step-number">1</span>
<h3 class="step-title">Demand consultation</h3>
<p class="step-desc">The customer sends a contact email to get the consultation.</p>
</div>
</div>
<!-- 步骤 2 -->
<div class="process-step">
<div class="step-icon">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/kefu.png" alt="设计">
</div>
<div class="step-content">
<span class="step-number">2</span>
<h3 class="step-title">Solution Design</h3>
<p class="step-desc">The business manager conducts content docking with the customer.</p>
</div>
</div>
<!-- 步骤 3 -->
<div class="process-step">
<div class="step-icon">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/emptybox.png" alt="实施">
</div>
<div class="step-content">
<span class="step-number">3</span>
<h3 class="step-title">Professional implementation</h3>
<p class="step-desc">We make a samptle according to the customer's requirements and confirm the details.</p>
</div>
</div>
<!-- 步骤 4 -->
<div class="process-step">
<div class="step-icon">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/woshou.png" alt="交付">
</div>
<div class="step-content">
<span class="step-number">4</span>
<h3 class="step-title">Successfully placed order</h3>
<p class="step-desc">After the customer's confirmation,the customer pays the deposit and places the order.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 模块2:3D轮播 -->
<div id="module2" class="module">
<div class="module-content">
<!-- 代码2的内容 -->
<div class="fp-carousel-module">
<div class="fp-carousel-container">
<div class="fp-carousel-item fp-active" data-index="0">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-14_59_30_compressed.png" alt="Printing">
<div class="fp-description">Printing:Transfer your design onto paper or board using offset, digital or flexo presses.</div>
</div>
<div class="fp-carousel-item fp-next" data-index="1">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_02_51_compressed.png" alt="Surface Finishing">
<div class="fp-description">Surface Finishing:Enhance and protect the print by adding coatings or varnishes (e.g. UV, matte or gloss).</div>
</div>
<div class="fp-carousel-item fp-next-far" data-index="2">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_05_48_compressed.png">
<div class="fp-description">Lamination (Mounting):Bond the printed sheet to a sturdier substrate or apply a clear film for extra durability.</div>
</div>
<极 class="fp-carousel-item fp-prev" data-index="3">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_11_40_compressed.png" alt="Die-Cutting">
<div class="fp-description">Die-Cutting:Use a custom metal die to cut out shapes, create windows or trim the edges precisely.</div>
</div>
<div class="fp-carousel-item fp-prev-far" data-index="4">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年极月18日-15_21_01_compressed.png">
<div class="fp-description">Gluing & Assembly:Fold and glue the die-cut pieces together to form boxes, folders or other finished items.</div>
</div>
<div class="fp-carousel-item fp-prev-far" data-index="5">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-15_24_28_compressed.png" alt="Packing & Shipping">
<div class="fp-description">Packing & Shipping:Stack, bundle or carton the completed products, then palletize and dispatch them to the client.</div>
</div>
<div class="fp-nav-btn fp-prev-btn">
<div class="fp-arrow">❮</div>
</div>
<div class="fp-nav-btn fp-next-btn">
<div class="fp-arrow">❯</div>
</div>
</div>
</div>
</div>
</div>
<!-- 模块3:材料展示 -->
<div id="module3" class="module">
<div class="module-content">
<!-- 代码3的内容 -->
<div class="luxemg-container">
<!-- Paper board 部分 -->
<h2 class="luxemg-section-title">Paper board</h2>
<div class="luxemg-grid">
<!-- SBS C1S -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_59_47_compressed.png"
alt="SBS C1S"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">SBS C1S</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-sbs-c1s">VIEW MORE</button>
</div>
</div>
<!-- SBS C2S -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_45_42_compressed.png"
alt="SBS C2S"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">SBS C2S</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-sbs-c2s">VIEW MORE</button>
</div>
</div>
<!-- CCNB -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_44_52_compressed.png"
alt="CCNB"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">CCNB</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-ccnb">VIEW MORE</button>
</极>
</div>
<!-- UUK -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=UUK"
alt="UUK"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">UUK</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-uuk">VIEW MORE</button>
</div>
</div>
<!-- Metallic -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=Metallic"
alt="Metallic"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">Metallic</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-metallic">VIEW MORE</button>
</div>
</div>
</div>
<!-- Corrugated 部分 -->
<h2 class="luxemg-section-title">Corrugated</h2>
<!-- single wall部分 -->
<h3 class="luxemg-subsection-title">single wall</h3>
<div class="luxemg-grid">
<!-- A Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=A+Flute"
alt="A Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">A Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-a-flute">VIEW MORE</button>
</div>
</div>
<!-- C Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=C+Flute"
alt="C Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">C Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-c-flute">VIEW MORE</button>
</div>
</div>
<!-- B Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=B+Flute"
alt="B Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">B Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-b-flute">VIEW MORE</button>
</div>
</div>
<!-- E Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=E+Flute"
alt="E Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">E Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-e-flute">VIEW MORE</button>
</div>
</div>
<!-- F Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=F+Flute"
alt="F Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">F Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-f-flute">VIEW MORE</button>
</div>
</div>
</div>
<!-- double wall部分 -->
<h3 class="luxemg-subsection-title">double wall</h3>
<div class="luxemg-grid">
<!-- B/C Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=B/C+Flute"
alt="B/C Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">B/C Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-bc-flute">VIEW MORE</button>
</div>
</div>
<!-- E/C Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=E/C+Flute"
alt="E/C Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">E/C Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-ec-flute">VIEW MORE</button>
</div>
</div>
<!-- E/B Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=E/B+Flute"
alt="E/B Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">E/B Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-eb-flute">VIEW MORE</button>
</div>
</div>
<!-- F/E Flute -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=F/E+Flute"
alt="F/E Flute"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">F/E Flute</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-fe-flute">VIEW MORE</button>
</div>
</div>
</div>
<!-- Print 部分 -->
<h2 class="luxemg-section-title">Print</h2>
<div class="luxemg-grid">
<!-- CMYK -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=CMYK"
alt="CMYK"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">CMYK</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-cmyk">VIEW MORE</button>
</div>
</div>
<!-- Pantone -->
<div class="luxemg-card">
<div class="luxemg-card-image">
<img src="https://via.placeholder.com/300x240?text=Pantone"
alt="Pantone"
class="luxemg-card-img">
</div>
<div class="luxemg-card-content">
<h3 class="luxemg-card-title">Pantone</h3>
<button class="luxemg-detail-btn" data-luxemg-modal="modal-pantone">VIEW MORE</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 模块4:图片轮播 -->
<div id="module4" class="module">
<div class="module-content">
<!-- 代码4的内容 -->
<div class="carousel-container">
<!-- 轮播轨道 -->
<div class="carousel">
<!-- 轮播项1 -->
<div class="carousel-item">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Lamination-Gloss_Matte1_compressed.png" alt="Lamination (Gloss/Matte)">
<div class="image-info">
<h3>Lamination (Gloss/Matte)</h3>
<p>– Applying a thin plastic film over the printed sheet to enhance scratch resistance, moisture protection and overall durability. Gloss lamination yields a shiny surface, while matte lamination gives a low-sheen, soft-touch effect.</p>
</div>
</div>
<!-- 轮播项2 -->
<div class="carousel-item">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/UV-Coating-Spot_Overall_compressed.png" alt="UV Coating (Spot/Overall)">
<div class="image-info">
<h3>UV Coating (Spot/Overall)</h3>
<p>– Spreading a liquid UV-curable varnish onto either selected areas (spot UV) or the entire sheet, then instantly curing it under UV light. Creates high gloss and tactile contrast.</p>
</div>
</div>
<!-- 轮播项3 -->
<div class="carousel-item">
<img src="极ttps://www.fetchingpack.com/wp-content/uploads/2025/06/Hot-Foil-Stamping_compressed.png" alt="Hot Foil Stamping">
<div class="image-info">
<h3>Hot Foil Stamping</h3>
<p>– Transferring metallic or pigmented foil onto specific areas of the print using heat and pressure. Delivers a premium metallic sheen (gold, silver, colored foils) for logos or decorative accents.</p>
</div>
</div>
<!-- 轮播项4 -->
<div class="carousel-item">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Embossing-_-Debossing1_compressed.png" alt="Embossing / Debossing">
<div class="image-info">
<h3>Embossing / Debossing</h3>
<p>– Pressing the paper between male and female dies to create a raised (emboss) or recessed (deboss) 3D relief. Adds tactile interest and a sense of depth.</p>
</div>
</div>
<!-- 轮播项5 -->
<div class="carousel-item">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Die-Cutting_compressed.png" alt="Die-Cutting">
<div class="image-info">
<h3>Die-Cutting</h3>
<p>– Using a custom-made metal die to cut the printed sheet into precise shapes or create windows/slots. Essential for producing custom box shapes, hang-tabs, or intricate cut-outs.</p>
</div>
</div>
<!-- 轮播项6 -->
<div class="carousel-item">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Creasing-Folding-Crease_compressed.png" alt="Creasing (Folding Crease)">
<div class="image-info">
<h3>Creasing (Folding Crease)</h3>
<p>– Impressing a crease line on the sheet to facilitate clean, accurate folds without cracking the coating or ink. Critical for boxes, folders, and other folded structures.</p>
</div>
</div>
<!-- 轮播项7 -->
<div class="carousel-item">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Spot-UV-Emboss-Combination_compressed.png" alt="Spot UV + Emboss Combination">
<div class="image-info">
<h3>Spot UV + Emboss Combination</h3>
<p>– First applying spot UV coating, then embossing the same area to create a shiny, raised element. Enhances both visual shine and tactile relief simultaneously.</p>
</div>
</div>
<!-- 轮播项8 -->
<div class="carousel-item">
<img src="https://www.fetchingpack.com/wp-content/uploads/2025/06/Laser-Finishing-Holographic-Etch-Combination_compressed.png" alt="Holographic Foil Stamping">
<div class="image-info">
<h3>Holographic Foil Stamping</h3>
<p>— Laser-etch microscopic holographic patterns onto foil, then heat- or UV-cure to lock in vibrant, angle-shifting colors and subtle texture for a premium anti-counterfeiting finish.</p>
</div>
</div>
</div>
<!-- 控制按钮 -->
<div class="carousel-controls">
<button class="control-btn" id="prevBtn">Previous</button>
<button class="control-btn" id="nextBtn">next</button>
<button class="control-btn" id="autoBtn">暂停轮播</button>
</div>
<!-- 指示器 -->
<div class="indicator">
<div class="indicator-dot active" data-index="0"></div>
<div class="indicator-dot" data-index="1"></div>
<div class="indicator-dot" data-index="2"></div>
<div class="indicator-dot" data-index="3"></div>
<div class="indicator-dot" data-index="4"></div>
<div class="indicator-dot" data-index="5"></div>
<div class="indicator-dot" data-index="6"></div>
<div class="indicator-dot" data-index="7"></div>
</div>
</div>
</div>
</div>
</div>
<!-- 模态框容器 -->
<div id="luxemg-modal-container" class="luxemg-modal-container">
<div class="luxemg-modal-wrapper">
<div class="luxemg-modal-content">
<div class="luxemg-modal-header">
<h3 id="luxemg-modal-title" class="luxemg-modal-title">Material Details</h3>
<button id="luxemg-close-modal" class="luxemg-close-btn">×</button>
</div>
<div class="luxemg-modal-body">
<div class="luxemg-modal-image-container">
<img id="luxemg-modal-image" class="luxemg-modal-img" src="" alt="Material">
</div>
<div class="luxemg-modal-description">
<div id="luxemg-modal-description" class="luxemg-modal-desc"></div>
</div>
</div>
</div>
</div>
</div>
<!-- JavaScript -->
<script>
// 导航切换功能
document.addEventListener('DOMContentLoaded', function() {
// 导航切换
const navLinks = document.querySelectorAll('.nav-link');
const modules = document.querySelectorAll('.module');
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
// 获取目标模块ID
const targetId = this.getAttribute('data-target');
// 更新导航状态
navLinks.forEach(l => l.classList.remove('active'));
this.classList.add('active');
// 切换模块
modules.forEach(module => {
module.classList.remove('active');
});
document.getElementById(targetId).classList.add('active');
});
});
// 初始化模块2的轮播功能
initCarousel(document.querySelector('#module2 .fp-carousel-module'));
// 初始化模块3的模态框功能
initLuxemgGallery();
// 初始化模块4的轮播功能
initModule4Carousel();
});
// 模块2的轮播功能
function initCarousel(module) {
const container = module.querySelector('.fp-carousel-container');
const items = Array.from(module.querySelectorAll('.fp-carousel-item'));
const prevBtn = module.querySelector('.fp-prev-btn');
const nextBtn = module.querySelector('.fp-next-btn');
let currentIndex = 0;
let isAnimating = false;
// 初始化位置
updatePositions();
// 事件绑定函数
const bindEvents = function() {
// 图片点击事件
items.forEach(item => {
item.addEventListener('click', function(e) {
e.stopPropagation();
if (isAnimating) return;
isAnimating = true;
if (this.classList.contains('fp-next') || this.classList.contains('fp-next-far')) {
navigate(1);
}
else if (this.classList.contains('fp-prev') || this.classList.contains('fp-prev-far')) {
navigate(-1);
}
// 动画结束后重置标志
setTimeout(() => isAnimating = false, 700);
});
});
// 容器区域点击
container.addEventListener('click', function(e) {
if (isAnimating) return;
isAnimating = true;
const rect = container.getBoundingClientRect();
const clickX = e.clientX - rect.left;
if (clickX > rect.width * 3/4) {
navigate(1);
}
else if (clickX < rect.width * 1/4) {
navigate(-1);
}
setTimeout(() => isAnimating = false, 700);
});
// 导航按钮
prevBtn.addEventListener('click', function(e) {
e.stopPropagation();
if (isAnimating) return;
isAnimating = true;
navigate(-1);
setTimeout(() => isAnimating = false, 700);
});
nextBtn.addEventListener('click', function(e) {
e.stopPropagation();
if (isAnimating) return;
isAnimating = true;
navigate(1);
setTimeout(() => isAnimating = false, 700);
});
// 键盘导航
document.addEventListener('keydown', function(e) {
if (isAnimating) return;
isAnimating = true;
if (e.key === 'ArrowLeft') {
navigate(-1);
} else if (e.key === 'ArrowRight') {
navigate(1);
}
setTimeout(() => isAnimating = false, 700);
});
// 响应式调整
window.addEventListener('resize', function() {
updatePositions();
});
};
// 导航函数
function navigate(direction) {
currentIndex = (currentIndex + direction + items.length) % items.length;
updatePositions();
}
// 更新位置
function updatePositions() {
items.forEach((item, index) => {
item.classList.remove('fp-active', 'fp-prev', 'fp-next', 'fp-prev-far', 'fp-next-far', 'fp-hidden');
const position = (index - currentIndex + items.length) % items.length;
if (position === 0) {
item.classList.add('fp-active');
}
else if (position === 1) {
item.classList.add('fp-next');
}
else if (position === 2) {
item.classList.add('fp-next-far');
}
else if (position === items.length - 1) {
item.classList.add('fp-prev');
}
else if (position === items.length - 2) {
item.classList.add('fp-prev-far');
}
else {
item.classList.add('fp-hidden');
}
});
}
// 初始化事件绑定
bindEvents();
}
// 模块3的模态框功能
function initLuxemgGallery() {
// 材料详情数据
const luxemgMaterialDetails = {
// Paper board
"modal-sbs-c1s": {
title: "SBS C1S",
image: "https://www.fetchingpack.com/wp-content/uploads/2025/06/ChatGPT-Image-2025年6月18日-16_59_47_compressed.png",
description: "<p>SBS C1S(Solid Bleached Sulfate – Coated One Side) is a premium-grade paperboard made from 100% virgin bleached wood pulp. It is coated on one side to provide an exceptionally smooth and white printing surface, while the reverse side remains uncoated for functional versatility.</p><p>Key Features:<br>- Bright White Appearance: Produced from fully bleached fibers for a clean, uniform, and high-end look.<br>- Coated One Side (C1S): One side has a clay coating for excellent printability; the reverse side is uncoated for better glue adhesion or writing.<br>- Excellent Print Surface: Ideal for offset, digital, and specialty printing methods; supports vibrant color reproduction and fine detail.<br>- High Stiffness and Strength: Offers good structural integrity, making it suitable for rigid packaging and die-cut designs.<br>- Environmentally Friendly: Recyclable, biodegradable, and available with FSC certification upon request.</p><p>Main Advantages:<br>✅ Preferred choice for premium packaging (cosmetics, personal care, high-end retail)<br>✅ Superior surface for specialty finishes like foil stamping, embossing, and spot UV<br>✅ Balanced combination of print quality and converting performance<br>✅ Consistent white core and surface enhance the perceived value of the final product<br>✅ Compatible with folding, scoring, gluing, and other post-press operations</p>"
},
// ... 其他材料详情
};
// DOM元素引用
const luxemgModalContainer = document.getElementById('luxemg-modal-container');
const luxemgModalTitle = document.getElementById('luxemg-modal-title');
const luxemgModalImage = document.getElementById('luxemg-modal-image');
const luxemgModalDescription = document.getElementById('luxemg-modal-description');
const luxemgCloseModal = document.getElementById('luxemg-close-modal');
// 打开模态框函数
function openLuxemgModal(modalId) {
const material = luxemgMaterialDetails[modalId];
const modalContent = luxemgModalContainer.querySelector('.luxemg-modal-content');
if (!material) {
console.error("Material details not found for:", modalId);
return;
}
// 填充模态框内容
luxemgModalTitle.textContent = material.title;
luxemgModalImage.src = material.image;
luxemgModalImage.alt = material.title;
luxemgModalDescription.innerHTML = material.description;
// 显示模态框
luxemgModalContainer.style.display = 'block';
// 强制重绘确保动画执行
void luxemgModalContainer.offsetWidth;
// 应用显示动画
setTimeout(() => {
luxemgModalContainer.style.opacity = '1';
modalContent.style.transform = 'scale(1)';
modalContent.style.opacity = '1';
}, 10);
// 禁止背景滚动
document.body.style.overflow = 'hidden';
}
// 关闭模态框函数
function closeLuxemgModal() {
const modalContent = luxemgModalContainer.querySelector('.luxemg-modal-content');
luxemgModalContainer.style.opacity = '0';
modalContent.style.transform = 'scale(0.95)';
modalContent.style.opacity = '0';
setTimeout(() => {
luxemgModalContainer.style.display = 'none';
document.body.style.overflow = '';
}, 300);
}
// 事件绑定函数
luxemgCloseModal.addEventListener('click', closeLuxemgModal);
luxemgModalContainer.addEventListener('click', function(e) {
if (e.target === this) closeLuxemgModal();
});
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') closeLuxemgModal();
});
document.addEventListener('click', function(e) {
if (e.target.classList.contains('luxemg-detail-btn')) {
const modalId = e.target.getAttribute('data-l极emg-modal');
openLuxemgModal(modalId);
}
});
}
// 模块4的轮播功能
function initModule4Carousel() {
// 获取DOM元素
const carousel = document.querySelector('#module4 .carousel');
const items = document.querySelectorAll('#module4 .carousel-item');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const autoBtn = document.getElementById('autoBtn');
const dots = document.querySelectorAll('#module4 .indicator-dot');
// 初始化变量
let currentIndex = 0;
let itemsPerView = calculateItemsPerView();
let autoPlayInterval;
let isAutoPlay = true;
// 计算当前视图显示的项目数
function calculateItemsPerView() {
const width = window.innerWidth;
if (width <= 500) return 1;
if (width <= 700) return 2;
if (width <= 900) return 3;
return 4;
}
// 更新轮播位置
function updateCarousel() {
// 计算每个项目的宽度百分比
const itemWidth = 100 / itemsPerView;
// 计算偏移量
const offset = -currentIndex * itemWidth;
// 应用转换效果
carousel.style.transform = `translateX(${offset}%)`;
// 更新指示点状态
dots.forEach((dot, index) => {
dot.classList.toggle('active', index === currentIndex);
});
}
// 下一张
function nextSlide() {
// 计算最大索引
const maxIndex = items.length - itemsPerView;
// 更新当前索引(循环)
currentIndex = currentIndex >= maxIndex ? 0 : currentIndex + 1;
updateCarousel();
}
// 上一张
function prevSlide() {
// 计算最大索引
const maxIndex = items.length - itemsPerView;
// 更新当前索引(循环)
currentIndex = currentIndex <= 0 ? maxIndex : currentIndex - 1;
updateCarousel();
}
// 自动轮播
function startAutoPlay() {
if (isAutoPlay) {
// 设置轮播间隔
autoPlayInterval = setInterval(nextSlide, 3000);
// 更新按钮文本
autoBtn.textContent = 'stop';
}
}
// 停止自动轮播
function stopAutoPlay() {
// 清除轮播间隔
clearInterval(autoPlayInterval);
// 更新按钮文本
autoBtn.textContent = 'start';
}
// 切换自动轮播状态
function toggleAutoPlay() {
// 反转自动播放状态
isAutoPlay = !isAutoPlay;
if (isAutoPlay) {
startAutoPlay();
} else {
stopAutoPlay();
}
}
// 初始化轮播
function init() {
// 计算每屏显示数量
itemsPerView = calculateItemsPerView();
// 更新轮播位置
updateCarousel();
// 开始自动播放
startAutoPlay();
}
// 事件监听器
nextBtn.addEventListener('click', () => {
nextSlide();
// 如果自动播放已暂停,则停止轮播
if (!isAutoPlay) stopAutoPlay();
});
prevBtn.addEventListener('click', () => {
prevSlide();
// 如果自动播放已暂停,则停止轮播
if (!isAutoPlay) stopAutoPlay();
});
autoBtn.addEventListener('click', toggleAutoPlay);
// 为每个指示点添加点击事件
dots.forEach(dot => {
dot.addEventListener('click', () => {
// 获取并设置当前索引
currentIndex = parseInt(dot.getAttribute('data-index'));
updateCarousel();
// 如果自动播放已暂停,则停止轮播
if (!isAutoPlay) stopAutoPlay();
});
});
// 窗口大小变化时重新计算
window.addEventListener('resize', () => {
// 重新计算每屏显示数量
itemsPerView = calculateItemsPerView();
// 更新轮播位置
updateCarousel();
});
// 初始化轮播
init();
}
</script>
</body>
</html>
```
### 修改说明:
1. **按钮样式统一修改**:
```css
.luxemg-detail-btn,
.control-btn {
color: #0566a8; /* 蓝色文字 */
background: white; /* 白色背景 */
font-weight: 500;
padding: 8px 16px;
border-radius: 4px; /* 微微圆角 */
border: 2px solid #0566a8; /* 蓝色边框 */
transition: all 0.3s ease;
cursor: pointer;
}
.luxemg-detail-btn:hover,
.control-btn:hover {
background: rgba(5, 102, 168, 0.1);
}
```
这段代码将所有按钮(包括VIEW MORE按钮和轮播控制按钮)统一设置为蓝色文字(#0566a8),白色背景,并添加了4px圆角边框。
2. **指示点增加到8个**:
```html
<!-- 指示器 -->
<div class="indicator">
<div class="indicator-dot active" data-index="0"></div>
<div class="indicator-dot" data-index="1"></div>
<div class="indicator-dot" data-index="2"></div>
<div class="indicator-dot" data-index="3"></div>
<div class="indicator-dot" data-index="4"></div>
<div class="indicator-dot" data-index="5"></div>
<div class="indicator-dot" data-index="6"></div>
<div class="indicator-dot" data-index="7"></div>
</div>
```
添加了8个指示点,每个点对应一个轮播项,并调整了指示点容器的样式:
```css
.indicator {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 8px;
padding: 10px 0;
}
```
3. **其他优化**:
- 保留了原有的导航栏样式(已经是蓝色文字和圆角边框)
- 确保所有按钮在悬停时有相同的视觉反馈
- 指示点容器使用flex布局并支持换行,确保在小屏幕上也能正常显示所有点
这些修改保持了原有功能的同时,统一了按钮样式并增加了指示点数量,符合您的需求。
<div class="add-frame"> <!-- 协议选择区域 --> <div class="form-group"> <label class="form-label">所属协议:</label> <div class="input-group"> <el-button type="primary" class="btn confirm-btn" >指明协议</el-button > </div> </div> <!-- 帧操作区域 --> <div class="form-group"> <div class="btn-group"> <el-button type="primary" class="btn primary-btn" >+ 新建帧</el-button > <el-select style="margin-top: 20px; width: 140px; display: block" placeholder="选择帧" > <el-option /> </el-select> <!-- 选择每一帧的参数 --> <el-select style="margin-top: 10px; width: 140px; display: block" placeholder="选择参数" clearable > <el-option /></el-select> </div> </div> <!-- !-- 帧详细信息 --> <div class="form-group"> <label class="form-label">帧标识:</label> {{ frame.frameIdcode }} </div> <div class="form-group"> <label class="form-label">帧名称:</label> {{ frame.name }} </div> <div class="form-group"> <label class="form-label">简述:</label> {{ frame.desc }} </div> </div> .add-frame { background-color: #e2f2f2; flex: 0 0 30%; /* 不伸缩、基准宽度30% */ border-right: 1px solid #ccc; /* 右侧分隔线 */ padding: 20px; /* 内边距 */ box-sizing: border-box; /* 包含边框在宽度计算中 */ }添加css,使用elementui进行美化
<think>好的,我现在需要帮助用户美化他们提供的Vue组件,使用Element UI和自定义CSS。首先,我要仔细分析用户提供的代码和需求。
用户给出的代码是一个包含协议选择、帧操作和帧信息显示的区域,结构上使用了多个form-group和Element UI的组件,比如el-button、el-select、el-option。当前的CSS是.add-frame的样式,用户希望用Element UI进行美化,并添加自定义CSS。
首先,我需要检查现有的HTML结构是否符合Element UI的最佳实践。比如,表单部分是否使用了el-form和el-form-item来包裹,这样可以利用Element UI的布局和样式。当前的代码中,form-group可能没有使用el-form-item,这可能导致样式不一致。
接下来,考虑布局。用户希望侧边栏效果,.add-frame设置了flex: 0 0 30%,可能需要调整内部元素的排列,使用更灵活的布局方式,比如Flexbox或Grid,确保元素在不同屏幕尺寸下表现良好。
然后,查看现有的Element UI组件。例如,按钮使用了el-button,但可能没有正确应用类型(如primary、success)或尺寸(如small、medium)。需要确认按钮的type和class是否合适,以及是否使用了Element UI的图标或其他功能。
对于el-select组件,用户可能需要调整宽度、间距,或者添加更清晰的标签。当前的代码中,el-select的placeholder是“选择帧”和“选择参数”,可能需要关联到数据模型,并确保选项动态生成。
帧信息显示部分使用了双花括号插值,可能需要使用el-input或el-input-number等表单组件来增强交互性,尤其是在编辑模式下。但根据用户提供的代码,当前是只读显示,所以可能需要保持现状,或者考虑使用el-descriptions来展示信息,提升美观度。
CSS方面,用户现有的.add-frame设置了背景色、边框和内边距。需要确保自定义CSS不与Element UI的默认样式冲突,可能需要调整类名或使用更具体的选择器。同时,考虑响应式设计,比如在不同屏幕宽度下的布局调整。
美化建议包括:
1. 使用el-form和el-form-item包裹表单元素,以利用Element的内置样式。
2. 调整按钮的排列,使用Element的布局组件如el-row和el-col来对齐。
3. 为el-select添加更合适的宽度和间距,可能使用下拉框的远程搜索或过滤功能。
4. 使用el-descriptions或el-card来美化帧信息的显示区域,使其更结构化和美观。
5. 自定义CSS中,添加过渡效果、阴影或圆角,提升视觉吸引力。
6. 确保颜色方案与Element UI的主题一致,比如主色、成功色等。
可能的代码调整包括将form-group替换为el-form-item,为按钮添加图标,调整el-select的样式,以及使用更合适的布局类。同时,自定义CSS需要覆盖或增强Element UI的默认样式,比如调整背景色、边框等,但要注意避免使用!important,除非必要。
最后,需要确保所有改动后的代码在Vue中正确运行,数据绑定正确,并且样式在不同浏览器下保持一致。测试响应式布局,确保侧边栏在移动设备上的显示效果。</think>以下是基于Element UI的美化方案及代码实现:
```vue
<template>
<div class="add-frame-container">
<el-form label-position="top" class="frame-form">
<!-- 协议选择区域 -->
<el-form-item label="所属协议:" class="form-section">
<el-button type="primary" icon="el-icon-document-checked">
指明协议
</el-button>
</el-form-item>
<!-- 帧操作区域 -->
<el-form-item label="帧操作:" class="form-section">
<div class="operation-group">
<el-button
type="success"
icon="el-icon-circle-plus-outline"
class="primary-btn"
style="margin-bottom: 15px">
+ 新建帧
</el-button>
<el-select
v-model="selectedFrame"
placeholder="选择帧"
class="frame-select"
clearable
filterable
>
<el-option
v-for="item in frameOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select
v-model="selectedParam"
placeholder="选择参数"
class="param-select"
clearable
filterable
>
<el-option
v-for="item in paramOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</el-form-item>
<!-- 帧详细信息 -->
<div class="info-section">
<el-descriptions title="帧详细信息" :column="1" border>
<el-descriptions-item label="帧标识">
<el-tag type="info">{{ frame.frameIdcode }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="帧名称">
<el-text class="info-text">{{ frame.name }}</el-text>
</el-descriptions-item>
<el-descriptions-item label="简述">
<el-text class="info-text">{{ frame.desc }}</el-text>
</el-descriptions-item>
</el-descriptions>
</div>
</el-form>
</div>
</template>
<style scoped>
.add-frame-container {
background: linear-gradient(145deg, #f0f9ff, #e2f2f2);
flex: 0 0 30%;
border-right: 1px solid #e4e7ed;
padding: 24px;
box-sizing: border-box;
height: 100vh;
overflow-y: auto;
}
.frame-form {
background: rgba(255, 255, 255, 0.9);
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.form-section {
margin-bottom: 24px;
padding: 16px;
background: #f8fafc;
border-radius: 6px;
}
.operation-group {
display: flex;
flex-direction: column;
gap: 12px;
}
.frame-select,
.param-select {
width: 100%;
}
.info-section {
margin-top: 20px;
padding: 16px;
background: #ffffff;
border: 1px solid #ebeef5;
border-radius: 6px;
}
.info-text {
font-size: 14px;
color: #606266;
}
.el-descriptions__title {
font-size: 16px;
color: #303133;
margin-bottom: 16px;
}
.el-tag {
margin: 4px 0;
}
</style>
<script>
export default {
data() {
return {
selectedFrame: '',
selectedParam: '',
frameOptions: [
{ value: 'frame1', label: '帧1' },
{ value: 'frame2', label: '帧2' }
],
paramOptions: [
{ value: 'param1', label: '参数1' },
{ value: 'param2', label: '参数2' }
],
frame: {
frameIdcode: 'ID-001',
name: '默认帧',
desc: '基础配置帧'
}
}
}
}
</script>
```
优化要点解释:
1. 使用`el-form`和`el-form-item`进行表单结构组织
2. 添加`el-descriptions`组件展示详细信息,提升数据可视化
3. 采用Element UI的布局系统(flex布局)进行组件排列
4. 增加渐变背景和阴影效果增强层次感
5. 使用`filterable`属性增强下拉框的搜索功能
6. 添加图标提升操作直观性
7. 采用Element UI的Tag组件展示标识信息
8. 增加响应式设计(height: 100vh + overflow-y: auto)
阅读全文
相关推荐







------------------------ test.js ------------------------
// 全局变量
let currentSort = { column: null, direction: 'asc' };
let currentPage = 1;
const pageSize = 10;
let filteredResults = [];
//监听来自父窗口的消息
window.addEventListener('message', function(event) {
if (event.source === window.parent && event.data === 'DataManagerReady') {
initializeDataManager();
}
});
// 初始化数据管理器
function initializeDataManager() {
const dataManager = window.parent.dataManager;
if (dataManager) {
// 注册数据刷新回调
dataManager.registerCallback('all', function(operation, entity, data) {
updatePageData(dataManager);
});
// 初始页面数据更新
updatePageData(dataManager);
// 设置搜索功能
setupSearch(dataManager);
// 设置排序功能
setupSorting();
// 设置分页事件
setupPagination();
} else {
console.error('DataManager not available');
}
}
// 更新页面数据
function updatePageData(dataManager) {
updateStats(dataManager);
updateTable(dataManager);
$('#lastUpdate').text(new Date().toLocaleTimeString());
}
// 更新统计卡片数据
function updateStats(dataManager) {
const data = dataManager.data;
$('#orderCount').text(data.dingdans?.length || 0);
$('#productCount').text(data.chanpins?.length || 0);
$('#materialCount').text(data.bancais?.length || 0);
const totalStock = data.kucuns?.reduce((sum, kucun) => sum + kucun.shuliang, 0) || 0;
$('#totalStock').text(totalStock);
}
// 更新结果表格
function updateTable(dataManager) {
const data = dataManager.data;
filteredResults = [];
// 处理订单产品数据
if (data.dingdan_chanpins) {
data.dingdan_chanpins.forEach(dc => {
if (!dc.dingdan || !dc.chanpin) return;
if (dc.chanpin.chanpin_zujians) {
dc.chanpin.chanpin_zujians.forEach(cz => {
if (!cz.zujian || !cz.bancai) return;
const bancai = cz.bancai;
const materialInfo = getMaterialInfo(bancai);
// 查找该板材的库存
const kucun = data.kucuns?.find(k => k.bancai?.id === bancai.id);
const stockQuantity = kucun ? kucun.shuliang : 0;
filteredResults.push({
orderNumber: dc.dingdan.number,
productInfo: dc.chanpin.bianhao,
productQuantity: dc.shuliang,
component: cz.zujian.name,
material: materialInfo,
materialPerComponent: cz.one_howmany,
materialOrderQuantity: dc.shuliang * cz.one_howmany,
stockQuantity: stockQuantity,
raw: {
orderNumber: dc.dingdan.number,
productQuantity: dc.shuliang,
materialPerComponent: cz.one_howmany,
materialOrderQuantity: dc.shuliang * cz.one_howmany,
stockQuantity: stockQuantity,
thickness: bancai.houdu || 0
},
bancaiId: bancai.id
});
});
}
});
}
// 处理订单板材数据 (Dingdan_bancai)
if (data.dingdan_bancais) {
data.dingdan_bancais.forEach(db => {
if (!db.dingdan || !db.bancai) return;
const bancai = db.bancai;
const materialInfo = getMaterialInfo(bancai);
// 查找该板材的库存
const kucun = data.kucuns?.find(k => k.bancai?.id === bancai.id);
const stockQuantity = kucun ? kucun.shuliang : 0;
// 确定产品信息
let productInfo = '独立订购';
if (db.chanpin) {
productInfo = db.chanpin.bianhao;
}
// 确定组件信息
let component = '独立板材';
if (db.zujian) {
component = db.zujian.name;
} else if (db.chanpin) {
component = '产品板材';
}
filteredResults.push({
orderNumber: db.dingdan.number,
productInfo: productInfo,
productQuantity: db.shuliang, // 直接订购的板材数量
component: component,
material: materialInfo,
materialPerComponent: 1, // 直接订购时,每件用量为1
materialOrderQuantity: db.shuliang,
stockQuantity: stockQuantity,
raw: {
orderNumber: db.dingdan.number,
productQuantity: db.shuliang,
materialPerComponent: 1,
materialOrderQuantity: db.shuliang,
stockQuantity: stockQuantity,
thickness: bancai.houdu || 0
},
bancaiId: bancai.id
});
});
}
// 应用排序
if (currentSort.column !== null) {
filteredResults = sortResults(filteredResults, currentSort.column, currentSort.direction);
}
// 渲染表格和分页
renderTable();
renderPagination();
}
// 渲染表格数据
function renderTable() {
const $tableBody = $('#resultBody');
$tableBody.empty();
const startIndex = (currentPage - 1) * pageSize;
const pageData = filteredResults.slice(startIndex, startIndex + pageSize);
if (pageData.length === 0) {
$('#noResults').show();
$('#paginationContainer').hide();
} else {
$('#noResults').hide();
$('#paginationContainer').show();
pageData.forEach(row => {
const $tr = $('');
$tr.append(${row.orderNumber} );
$tr.append(${row.productInfo} );
$tr.append(${row.productQuantity} );
$tr.append(${row.component} );
$tr.append(${row.material} );
$tr.append(${row.materialPerComponent} );
$tr.append(${row.materialOrderQuantity} );
$tr.append(${row.stockQuantity} );
$tr.append(<button class="btn btn-sm btn-outline-primary" onclick="showMaterialDetail(${row.bancaiId})">详情</button> );
$tableBody.append($tr);
});
}
$('#resultCount').text(filteredResults.length);
}
// 排序函数
function sortResults(results, columnIndex, direction) {
return results.sort((a, b) => {
// 根据列索引确定排序字段
let field;
switch(columnIndex) {
case 0: field = 'orderNumber'; break;
case 1: field = 'productInfo'; break;
case 2: field = 'productQuantity'; break;
case 3: field = 'component'; break;
case 4: return sortByThickness(a, b, direction); // 特殊处理:按厚度排序
case 5: field = 'materialPerComponent'; break;
case 6: field = 'materialOrderQuantity'; break;
case 7: field = 'stockQuantity'; break;
default: return 0;
}
// 数值排序
if (['productQuantity', 'materialPerComponent', 'materialOrderQuantity', 'stockQuantity'].includes(field)) {
return sortNumeric(a.raw[field], b.raw[field], direction);
}
// 字符串排序
return sortString(a[field], b[field], direction);
});
}
// 按厚度排序
function sortByThickness(a, b, direction) {
return sortNumeric(a.raw.thickness, b.raw.thickness, direction);
}
// 数值排序
function sortNumeric(aVal, bVal, direction) {
const aNum = parseFloat(aVal) || 0;
const bNum = parseFloat(bVal) || 0;
return direction === 'asc' ? aNum - bNum : bNum - aNum;
}
// 字符串排序
function sortString(aVal, bVal, direction) {
const aStr = String(aVal).toLowerCase();
const bStr = String(bVal).toLowerCase();
if (aStr < bStr) return direction === 'asc' ? -1 : 1;
if (aStr > bStr) return direction === 'asc' ? 1 : -1;
return 0;
}
// 获取板材详细信息函数
function getMaterialInfo(bancai) {
if (!bancai) return '未知板材';
// 获取材质名称
const caizhiName = bancai.caizhi?.name || '未知材质';
// 获取木皮信息
const formatMupi = (mupi) => {
if (!mupi) return null;
return ${mupi.name}${mupi.you ? '(油)' : ''};
};
const mupi1Str = formatMupi(bancai.mupi1) || '无';
const mupi2Str = formatMupi(bancai.mupi2) || '无';
const mupiInfo = mupi1Str + (mupi2Str !== '无' ? /${mupi2Str} : '');
// 厚度转换为字符串
const thickness = bancai.houdu ? ${bancai.houdu.toFixed(1)}mm : '未知厚度';
return ${caizhiName}-${mupiInfo} (${thickness});
}
// 设置搜索功能
function setupSearch(dataManager) {
// 订单搜索
$('#orderSearch').on('input', function() {
filterTable($(this).val().toLowerCase(), 0);
});
// 产品搜索
$('#productSearch').on('input', function() {
filterTable($(this).val().toLowerCase(), 1);
});
// 板材材质搜索
$('#materialSearch').on('input', function() {
filterTable($(this).val().toLowerCase(), 4);
});
// 木皮搜索
$('#woodSearch').on('input', function() {
const searchTerm = $(this).val().toLowerCase();
// 支持中文和数字搜索
const searchKeywords = {
'有油': '有油', '无油': '无油',
'you': '有油', 'wu': '无油',
'1': '有油', '0': '无油',
'(油)': '(油)'
};
const actualTerm = searchKeywords[searchTerm] || searchTerm;
filterTable(actualTerm, 4);
});
// 厚度搜索
$('#thicknessSearch').on('input', function() {
filterTable($(this).val().toLowerCase(), 4);
});
// 库存状态搜索
$('#stockStatusBtn').on('click', function() {
const minStock = parseInt($('#minStock').val()) || 0;
const maxStock = parseInt($('#maxStock').val()) || Number.MAX_SAFE_INTEGER;
filterByStock(minStock, maxStock);
});
// 重置搜索
$('#resetSearch').on('click', function() {
$('.search-input').val('');
currentPage = 1;
updateTable(window.parent.dataManager);
});
}
// 设置排序功能
function setupSorting() {
// 获取所有表头
$('#resultsTable th[data-sortable]').each((index, header) => {
$(header).on('click', () => {
// 更新排序状态
if (currentSort.column === index) {
currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc';
} else {
currentSort.column = index;
currentSort.direction = 'asc';
}
// 更新UI
updateSortIndicators();
// 重新排序和渲染表格
filteredResults = sortResults(filteredResults, currentSort.column, currentSort.direction);
renderTable();
renderPagination();
});
});
}
// 设置分页功能
function setupPagination() {
// 分页按钮事件委托
$('#paginationContainer').on('click', '.page-link', function(e) {
e.preventDefault();
const action = $(this).data('action');
if (action === 'prev' && currentPage > 1) {
currentPage--;
} else if (action === 'next' && currentPage < Math.ceil(filteredResults.length / pageSize)) {
currentPage++;
} else if (action === 'page') {
currentPage = parseInt($(this).data('page'));
}
renderTable();
renderPagination();
});
}
// 渲染分页控件
function renderPagination() {
const $pagination = $('#pagination');
$pagination.empty();
const totalPages = Math.ceil(filteredResults.length / pageSize);
if (totalPages <= 1) return;
// 添加上一页按钮
$pagination.append(
上一页
);
// 添加页码按钮
const startPage = Math.max(1, currentPage - 2);
const endPage = Math.min(totalPages, startPage + 4);
for (let i = startPage; i <= endPage; i++) {
$pagination.append(
${i}
);
}
// 添加下一页按钮
$pagination.append(
下一页
);
// 显示页码信息
$('#pageInfo').text(第 ${currentPage} 页,共 ${totalPages} 页);
}
// 更新排序指示器
function updateSortIndicators() {
// 清除所有指示器
$('#resultsTable th[data-sortable] .sort-indicator').text('');
// 为当前排序列添加指示器
if (currentSort.column !== null) {
const $currentHeader = $(#resultsTable th[data-sortable]:eq(${currentSort.column}));
$currentHeader.find('.sort-indicator').text(currentSort.direction === 'asc' ? '↑' : '↓');
}
}
// 表格过滤函数
function filterTable(searchTerm, columnIndex) {
currentPage = 1; // 重置到第一页
if (!searchTerm) {
updateTable(window.parent.dataManager);
return;
}
const $rows = $('#resultBody tr');
let visibleCount = 0;
$rows.each(function() {
const $cell = $(this).find(td:eq(${columnIndex}));
const cellText = $cell.text().toLowerCase();
let isMatch = false;
// 特殊处理油状态搜索
if (searchTerm === '有油' || searchTerm === '无油' || searchTerm === '(油)') {
isMatch = cellText.includes(searchTerm);
}
// 处理厚度字符串匹配
else if (columnIndex === 4 && !isNaN(parseFloat(searchTerm))) {
// 提取厚度数字部分进行匹配
const thicknessMatch = cellText.match(/(\d+\.?\d*)/);
if (thicknessMatch) {
const thicknessValue = parseFloat(thicknessMatch[1]);
const searchValue = parseFloat(searchTerm);
// 允许小数点误差
isMatch = Math.abs(thicknessValue - searchValue) < 0.5;
}
}
// 常规文本匹配
else {
isMatch = cellText.includes(searchTerm);
}
if (isMatch) {
$(this).show();
visibleCount++;
} else {
$(this).hide();
}
});
$('#resultCount').text(visibleCount);
$('#noResults').toggle(visibleCount === 0);
$('#paginationContainer').toggle(visibleCount > 0);
}
// 按库存量过滤
function filterByStock(minStock, maxStock) {
currentPage = 1; // 重置到第一页
const $rows = $('#resultBody tr');
let visibleCount = 0;
$rows.each(function() {
const $stockCell = $(this).find('td:eq(7)');
const stockText = $stockCell.text();
const stockValue = parseInt(stockText) || 0;
const isMatch = stockValue >= minStock && stockValue <= maxStock;
if (isMatch) {
$(this).show();
visibleCount++;
} else {
$(this).hide();
}
});
$('#resultCount').text(visibleCount);
$('#noResults').toggle(visibleCount === 0);
$('#paginationContainer').toggle(visibleCount > 0);
}
// 显示板材详情模态框
function showMaterialDetail(bancaiId) {
const dataManager = window.parent.dataManager;
if (!dataManager) return;
const bancais = dataManager.data.bancais || [];
const bancai = bancais.find(b => b.id === bancaiId);
const kucun = dataManager.data.kucuns?.find(k => k.bancai?.id === bancaiId);
if (!bancai) {
alert('未找到板材信息');
return;
}
// 格式化木皮信息
const formatMupiDetail = (mupi) => {
if (!mupi) return '无';
return ${mupi.name}${mupi.you ? '(油)' : ''};
};
// 获取相关订单
const relatedOrders = getRelatedOrders(bancai);
// 构建详情HTML
const detailHtml =
基本信息
ID: ${bancai.id}
材质: ${bancai.caizhi?.name || '未知'}
厚度: ${bancai.houdu ? bancai.houdu.toFixed(1) + 'mm' : '未知'}
库存数量: ${kucun ? kucun.shuliang : 0}
表面处理
木皮1: ${formatMupiDetail(bancai.mupi1)}
木皮2: ${formatMupiDetail(bancai.mupi2)}
相关订单 (${relatedOrders.length})
订单号
下单日期
交货日期
${relatedOrders.map(order =>
${order.number}
${order.xiadan ? new Date(order.xiadan).toLocaleDateString() : '-'}
${order.jiaohuo ? new Date(order.jiaohuo).toLocaleDateString() : '-'}
).join('')}
;
// 设置模态框内容
$('#materialDetailContent').html(detailHtml);
// 显示模态框
const materialModal = new bootstrap.Modal('#materialDetailModal');
materialModal.show();
}
// 获取板材相关订单
function getRelatedOrders(bancai) {
const dataManager = window.parent.dataManager;
if (!dataManager) return [];
const orders = [];
const dingdan_bancais = dataManager.data.dingdan_bancais || [];
// 查找直接订单组件关联
dingdan_bancais.forEach(db => {
if (db.bancai?.id === bancai.id && db.dingdan && !orders.some(o => o.id === db.dingdan.id)) {
orders.push(db.dingdan);
}
});
// 查找产品组件关联
const chanpin_zujians = dataManager.data.chanpin_zujians || [];
chanpin_zujians.forEach(cz => {
if (cz.bancai?.id === bancai.id) {
const dingdan_chanpins = dataManager.data.dingdan_chanpins || [];
dingdan_chanpins.forEach(dc => {
if (dc.chanpin?.id === cz.chanpin?.id && dc.dingdan && !orders.some(o => o.id === dc.dingdan.id)) {
orders.push(dc.dingdan);
}
});
}
});
return orders;
}
// 页面加载时尝试初始化
if (window.parent) {
window.parent.postMessage('RequestDataManager', '*');
}
// 添加全局函数供按钮调用
window.showMaterialDetail = showMaterialDetail;
------------------------ test.html ------------------------
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>板材库存管理系统</title>
</head>
<body>
板材库存管理系统
查询订单、产品、板材及库存信息
高级搜索
<input type="text" class="form-control with-icon" id="orderSearch" placeholder="搜索订单号..." aria-label="订单号搜索">
<input type="text" class="form-control with-icon" id="productSearch" placeholder="搜索产品编号..." aria-label="产品编号搜索">
<input type="text" class="form-control with-icon" id="materialSearch" placeholder="搜索板材ID或材质..." aria-label="板材搜索">
<input type="text" class="form-control with-icon" id="woodSearch" placeholder="搜索木皮名称..." aria-label="木皮搜索">
<input type="number" class="form-control with-icon" id="thicknessSearch" placeholder="厚度(mm)" min="0" step="0.1">
<input type="number" class="form-control" id="minStock" placeholder="最小库存" min="0">
<input type="number" class="form-control" id="maxStock" placeholder="最大库存" min="0">
<button class="btn btn-primary" type="button" id="stockStatusBtn">
</button>
<button class="btn btn-sm btn-outline-secondary" id="resetFilters">
重置筛选
</button>
查询结果
0 条记录
数据更新时间: --:--:--
订单号
产品信息
产品数量
组件
板材
单件用量
订单用量
库存数量
操作
加载中...
正在加载数据,请稍候...
没有找到匹配的记录
请尝试调整您的搜索条件
板材详情
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="../js/bootstrap-5.3.0-alpha1-dist/js/bootstrap.bundle.min.js"></script>
<script src="../js/test.js"></script>
</body>
</html>
实现排序和分页功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
首页
热门景点
特产美食
特产
美食
民俗文化
西河大鼓
吴桥杂技
河北梆子>
用户调研
![]()
![]()
![]()
![]()
![]()
石家庄
唐山
张家口
保定
秦皇岛
——河北宣传片——
这片土地既丰富又神秘
没有人知道
还有多少未知的物种等待去发现
而即便是那些已经被广泛知晓的物种
以我们目前的认知
也仅仅只掌握了密码的一小部分
每种生命都是复杂而珍贵的
尊重和爱护它们的密码
也是在保护我们自身的未来
人们未来美好生活的蓝图
建立在生物多样性的繁盛之上
这张蓝图宏伟且谦卑
它既承载着中国智慧
也承载着世界生态文明的未来
视频来源:河北文旅
<script src="js/js.js"></script>
</body>
</html>每行代码都是什么意思,每行代码全部打出来
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>硬件运维系统 - 报告管理</title>
</head>
<body>
报告管理
<input type="text" id="search-report" placeholder="搜索报告名称/类型">
<button class="btn" id="search-btn">搜索</button>
<button class="btn" id="sort-by-date">按日期排序</button>
<button class="btn btn-download" id="download-all">下载全部报告</button>
<button class="btn" id="add-report">新增报告</button>
新增报告
×
<form id="report-form">
<input type="hidden" id="report-id">
<label for="report-name">报告名称</label>
<input type="text" id="report-name" required>
<label for="report-type">报告类型</label>
<select id="report-type" required>
<option value="硬件故障处理报告">硬件故障处理报告</option>
<option value="软件运维报告">软件运维报告</option>
<option value="设备健康度报告">设备健康度报告</option>
<option value="产线运行分析报告">产线运行分析报告</option>
<option value="硬件日志采集报告">硬件选择 - 获取指定时间段的日志</option>
</select>
<label for="log-start-date">日志开始日期</label>
<input type="date" id="log-start-date" required>
<label for="log-end-date" style="margin-top: 10px;">日志结束日期</label>
<input type="date" id="log-end-date" required>
<label for="report-date">报告生成日期</label>
<input type="date" id="report-date" required>
<label for="report-content">报告内容</label>
请根据报告类型填写内容...
<textarea id="report-content" required></textarea>
<button type="button" class="btn" id="cancel-btn">取消</button>
<button type="submit" class="btn">保存</button>
</form>
<script src="style/js/jquery.min.js"></script>
<script>
// 检查登录状态
if (localStorage.getItem('isLogin') !== '1') {
window.location.href = 'login.html';
}
// 初始化报告数据和硬件日志数据
let reports = [];
let hardwareLogs = [];
// DOM 元素缓存
const $reportList = $('#report-list');
const $reportModal = $('#report-modal');
const $modalTitle = $('#modal-title');
const $reportForm = $('#report-form');
const $reportId = $('#report-id');
const $reportName = $('#report-name');
const $reportType = $('#report-type');
const $reportDate = $('#report-date');
const $reportContent = $('#report-content');
const $addReportBtn = $('#add-report');
const $cancelBtn = $('#cancel-btn');
const $closeBtn = $('.close');
const $searchBtn = $('#search-btn');
const $searchInput = $('#search-report');
const $sortByDateBtn = $('#sort-by-date');
const $downloadAllBtn = $('#download-all');
const $logTimeRange = $('.log-time-range');
const $contentDesc = $('#content-desc');
// 报告类型模板映射
const typeTemplates = {
'硬件故障处理报告': 1. 故障现象:
2. 故障排查过程:
3. 处理方案:
4. 处理结果:
5. 预防建议:,
'软件运维报告': 1. 运维内容:
2. 操作过程:
3. 运行状态:
4. 遗留问题:
5. 后续计划:,
'设备健康度报告': 1. 设备状态:
2. 检查项目:
3. 异常项:
4. 维护建议:
5. 预测分析:,
'产线运行分析报告': 1. 生产数据:
2. 设备表现:
3. 瓶颈分析:
4. 改进措施:
5. 提升建议:,
'硬件日志采集报告': ### 日志采集说明
- 采集时间段:{startDate} 至 {endDate}
- 涉及设备:自动从日志中提取
- 异常日志数量:{errorCount}
### 关键日志摘要
{logSummary}
};
// 从API加载报告数据
function loadReports() {
$.ajax({
url: 'api/reports.php',
method: 'GET',
dataType: 'json',
success: function (data) {
reports = data || [];
renderReports(reports);
},
error: function (xhr, status, error) {
console.error('加载报告失败:', error);
$reportList.html('加载报告数据失败,请稍后重试');
}
});
}
// 加载硬件日志数据
function loadHardwareLogs() {
$.getJSON('data/hardware_logs.json', (data) => {
hardwareLogs = data.logs || [];
console.log('硬件日志加载成功');
}).fail((xhr, status, error) => {
console.error('加载硬件日志失败:', error);
hardwareLogs = [];
});
}
// 渲染报告列表
function renderReports(reportData) {
$reportList.empty();
// 解绑之前的事件处理器,避免重复绑定
$reportList.off('click', '.edit-btn');
$reportList.off('click', '.delete-btn');
$reportList.off('click', '.download-btn');
if (reportData.length === 0) {
$reportList.html('暂无报告数据,请点击"新增报告"创建');
return;
}
reportData.forEach(report => {
const $card = $(
${report.name}
${report.type} |
生成日期:${report.date}
<button class="action-btn download-btn">下载</button>
<button class="action-btn edit-btn">编辑</button>
<button class="action-btn delete-btn">删除</button>
);
$reportList.append($card);
});
// 绑定事件
$reportList.on('click', '.edit-btn', function () {
const reportId = $(this).closest('.report-card').data('id');
editReport(reportId);
});
$reportList.on('click', '.delete-btn', function () {
const reportId = $(this).closest('.report-card').data('id');
deleteReport(reportId);
});
$reportList.on('click', '.download-btn', function () {
const reportId = $(this).closest('.report-card').data('id');
downloadReport(reportId);
});
}
// 打开模态框
function openModal(isEdit = false, report = null) {
$reportForm[0].reset();
$logTimeRange.hide();
$reportContent.val('');
if (isEdit && report) {
$modalTitle.text('编辑报告');
$reportId.val(report.id);
$reportName.val(report.name);
$reportType.val(report.type);
$reportDate.val(report.date);
$reportContent.val(report.content);
if (report.type === '硬件日志采集报告') {
$logTimeRange.show();
$('#log-start-date').val(report.logStartDate || '');
$('#log-end-date').val(report.logEndDate || '');
}
} else {
$modalTitle.text('新增报告');
$reportId.val('');
$reportDate.val(new Date().toISOString().split('T')[0]);
}
$reportModal.show();
}
// 关闭模态框
function closeModal() {
$reportModal.hide();
}
// 编辑报告
function editReport(id) {
console.log('编辑报告:', reports);
console.log('报告ID:', id);
const stringId = String(id);
const report = reports.find(r => r.id === stringId);
console.log('编辑报告:', report);
// console.log(r.id);
if (report) {
openModal(true, report);
} else {
alert('未找到该报告');
loadReports();
}
}
// 删除报告
function deleteReport(id) {
const stringId = String(id);
const report = reports.find(r => r.id === stringId);
if (!report) {
alert('未找到该报告');
loadReports();
return;
}
if (confirm(确定要删除"${report.name}"这份报告吗?删除后无法恢复!)) {
$.ajax({
url: 'api/reports.php',
method: 'DELETE',
contentType: 'application/json',
data: JSON.stringify({ id: id }),
dataType: 'json',
success: function (response) {
if (response.success) {
loadReports(); // 重新加载数据
} else {
alert('删除失败:' + (response.message || '未知错误'));
}
},
error: function (xhr, status, error) {
console.error('删除报告失败:', error);
alert('删除报告失败,请检查网络连接');
}
});
}
}
// 下载单个报告
function downloadReport(id) {
const report = reports.find(r => r.id === id);
if (!report) return;
let content =
报告名称:${report.name}
报告类型:${report.type}
生成日期:${report.date}
报告内容:
${report.content}
.trim();
if (report.type === '硬件日志采集报告' && report.attachments && report.attachments.length) {
content += \n\n=== 日志附件 ===\n;
report.attachments.forEach(attach => {
content += \n【附件:${attach.filename}】\n${attach.content}\n;
});
}
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = $('').attr({
href: url,
download: ${report.name.replace(/[\/:*?"<>|]/g, '-')}.txt
});
$('body').append(a);
a[0].click();
a.remove();
URL.revokeObjectURL(url);
}
// 下载全部报告
function downloadAllReports() {
if (reports.length === 0) {
alert('没有报告可下载');
return;
}
let allContent = '=== 所有报告汇总 ===\n\n';
reports.forEach((report, idx) => {
allContent += 【报告 ${idx + 1}】\n;
allContent += 名称:${report.name}\n类型:${report.type}\n日期:${report.date}\n\n;
allContent += 内容:\n${report.content}\n\n;
if (report.type === '硬件日志采集报告' && report.attachments && report.attachments.length) {
allContent += === 日志附件 ===\n;
report.attachments.forEach(attach => {
allContent += \n【附件:${attach.filename}】\n${attach.content}\n;
});
}
allContent += '========================================\n\n';
});
const blob = new Blob([allContent], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = $('').attr({
href: url,
download: 所有报告汇总_${new Date().toISOString().split('T')[0]}.txt
});
$('body').append(a);
a[0].click();
a.remove();
URL.revokeObjectURL(url);
}
// 保存报告
$reportForm.on('submit', function (e) {
e.preventDefault();
const formData = {
id: $reportId.val(),
name: $reportName.val(),
type: $reportType.val(),
date: $reportDate.val(),
content: $reportContent.val(),
attachments: []
};
if (formData.type === '硬件日志采集报告') {
const startDate = $('#log-start-date').val();
const endDate = $('#log-end-date').val();
formData.logStartDate = startDate;
formData.logEndDate = endDate;
const filteredLogs = hardwareLogs.filter(log => {
const logTime = new Date(log.timestamp);
const start = new Date(startDate);
const end = new Date(endDate);
return logTime >= start && logTime <= end;
});
if (filteredLogs.length > 0) {
const errorCount = filteredLogs.filter(log => log.level === 'ERROR').length;
const logSummary = filteredLogs.map(log =>
[${log.timestamp}] [${log.device}] [${log.level}]:${log.content}
).join('\n');
formData.content = typeTemplates['硬件日志采集报告']
.replace('{startDate}', startDate)
.replace('{endDate}', endDate)
.replace('{errorCount}', errorCount)
.replace('{logSummary}', logSummary);
formData.attachments.push({
filename: hardware_logs_${startDate}_${endDate}.txt,
content: filteredLogs.map(log =>
${log.timestamp}\n${log.device}\n${log.level}\n${log.content}\n-----\n
).join('')
});
} else {
formData.content = '未找到指定时间段的日志数据';
}
}
const method = formData.id ? 'PUT' : 'POST';
$.ajax({
url: 'api/reports.php',
method: method,
contentType: 'application/json',
data: JSON.stringify(formData),
dataType: 'json',
success: function (response) {
if (response.success) {
loadReports();
closeModal();
} else {
alert('保存失败:' + (response.message || '未知错误'));
}
},
error: function (xhr, status, error) {
console.error('保存报告失败:', error);
alert('保存报告失败,请检查网络连接');
}
});
});
// 搜索报告
function handleSearch() {
const keyword = $searchInput.val().toLowerCase();
const filtered = reports.filter(report =>
report.name.toLowerCase().includes(keyword) ||
report.type.toLowerCase().includes(keyword)
);
renderReports(filtered);
}
// 按日期排序
function sortReportsByDate() {
const sorted = [...reports].sort((a, b) =>
new Date(b.date) - new Date(a.date)
);
renderReports(sorted);
}
// 事件绑定
function bindEvents() {
// 报告类型切换
// / 修改报告类型切换事件
$reportType.on('change', function () {
const type = $(this).val();
const $startDate = $('#log-start-date');
const $endDate = $('#log-end-date');
$logTimeRange.hide();
$contentDesc.text('请根据报告类型填写内容...');
if (type === '硬件日志采集报告') {
$logTimeRange.show();
$contentDesc.text('选择时间段后将自动生成日志摘要');
$reportContent.val('');
// 仅在日志类型下添加必填属性
$startDate.attr('required', true);
$endDate.attr('required', true);
} else {
$reportContent.val(typeTemplates[type] || '');
// 其他类型下移除必填属性
$startDate.removeAttr('required');
$endDate.removeAttr('required');
}
});
// 新增报告
$addReportBtn.on('click', () => openModal());
// 关闭模态框
$closeBtn.on('click', closeModal);
$cancelBtn.on('click', closeModal);
// 点击模态框外部关闭
$(window).on('click', (e) => {
if ($(e.target).is($reportModal)) closeModal();
});
// 搜索
$searchBtn.on('click', handleSearch);
$searchInput.on('keypress', (e) => {
if (e.key === 'Enter') handleSearch();
});
// 排序
$sortByDateBtn.on('click', sortReportsByDate);
// 下载全部
$downloadAllBtn.on('click', downloadAllReports);
}
// 初始化
function init() {
bindEvents();
loadHardwareLogs();
loadReports();
}
// 页面加载完成后初始化
$(document).ready(init);
</script>
</body>
</html>
优化代码.让拟态窗更加好看





<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
首页
热门景点
特产美食
特产
美食
民俗文化
西河大鼓
吴桥杂技
河北梆子>
用户调研
![]()
![]()
![]()
![]()
![]()
石家庄
唐山
张家口
保定
秦皇岛
——河北宣传片——
这片土地既丰富又神秘
没有人知道
还有多少未知的物种等待去发现
而即便是那些已经被广泛知晓的物种
以我们目前的认知
也仅仅只掌握了密码的一小部分
每种生命都是复杂而珍贵的
尊重和爱护它们的密码
也是在保护我们自身的未来
人们未来美好生活的蓝图
建立在生物多样性的繁盛之上
这张蓝图宏伟且谦卑
它既承载着中国智慧
也承载着世界生态文明的未来
视频来源:河北文旅
<script src="js/js.js"></script>
</body>
</html>每行代码都是什么意思,每行代码全部打出来


<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>硬件运维系统 - 报告管理</title> </head> <body> 报告管理 <input type="text" id="search-report" placeholder="搜索报告名称/类型"> <button class="btn" id="search-btn">搜索</button> <button class="btn" id="sort-by-date">按日期排序</button> <button class="btn btn-download" id="download-all">下载全部报告</button> <button class="btn" id="add-report">新增报告</button> 新增报告 × <form id="report-form"> <input type="hidden" id="report-id"> <label for="report-name">报告名称</label> <input type="text" id="report-name" required> <label for="report-type">报告类型</label> <select id="report-type" required> <option value="硬件故障处理报告">硬件故障处理报告</option> <option value="软件运维报告">软件运维报告</option> <option value="设备健康度报告">设备健康度报告</option> <option value="产线运行分析报告">产线运行分析报告</option> <option value="硬件日志采集报告">硬件选择 - 获取指定时间段的日志</option> </select> <label for="log-start-date">日志开始日期</label> <input type="date" id="log-start-date" required> <label for="log-end-date" style="margin-top: 10px;">日志结束日期</label> <input type="date" id="log-end-date" required> <label for="report-date">报告生成日期</label> <input type="date" id="report-date" required> <label for="report-content">报告内容</label> 请根据报告类型填写内容... <textarea id="report-content" required></textarea> <button type="button" class="btn" id="cancel-btn">取消</button> <button type="submit" class="btn">保存</button> </form> <script src="style/js/jquery.min.js"></script> <script> // 检查登录状态 if (localStorage.getItem('isLogin') !== '1') { window.location.href = 'login.html'; } // 初始化报告数据和硬件日志数据 let reports = []; let hardwareLogs = []; // DOM 元素缓存 const $reportList = $('#report-list'); const $reportModal = $('#report-modal'); const $modalTitle = $('#modal-title'); const $reportForm = $('#report-form'); const $reportId = $('#report-id'); const $reportName = $('#report-name'); const $reportType = $('#report-type'); const $reportDate = $('#report-date'); const $reportContent = $('#report-content'); const $addReportBtn = $('#add-report'); const $cancelBtn = $('#cancel-btn'); const $closeBtn = $('.close'); const $searchBtn = $('#search-btn'); const $searchInput = $('#search-report'); const $sortByDateBtn = $('#sort-by-date'); const $downloadAllBtn = $('#download-all'); const $logTimeRange = $('.log-time-range'); const $contentDesc = $('#content-desc'); // 报告类型模板映射 const typeTemplates = { '硬件故障处理报告': 1. 故障现象: 2. 故障排查过程: 3. 处理方案: 4. 处理结果: 5. 预防建议:, '软件运维报告': 1. 运维内容: 2. 操作过程: 3. 运行状态: 4. 遗留问题: 5. 后续计划:, '设备健康度报告': 1. 设备状态: 2. 检查项目: 3. 异常项: 4. 维护建议: 5. 预测分析:, '产线运行分析报告': 1. 生产数据: 2. 设备表现: 3. 瓶颈分析: 4. 改进措施: 5. 提升建议:, '硬件日志采集报告': ### 日志采集说明 - 采集时间段:{startDate} 至 {endDate} - 涉及设备:自动从日志中提取 - 异常日志数量:{errorCount} ### 关键日志摘要 {logSummary} }; // 从API加载报告数据 function loadReports() { $.ajax({ url: 'api/reports.php', method: 'GET', dataType: 'json', success: function (data) { reports = data || []; renderReports(reports); }, error: function (xhr, status, error) { console.error('加载报告失败:', error); $reportList.html('加载报告数据失败,请稍后重试'); } }); } // 加载硬件日志数据 function loadHardwareLogs() { $.getJSON('data/hardware_logs.json', (data) => { hardwareLogs = data.logs || []; console.log('硬件日志加载成功'); }).fail((xhr, status, error) => { console.error('加载硬件日志失败:', error); hardwareLogs = []; }); } // 渲染报告列表 function renderReports(reportData) { $reportList.empty(); // 解绑之前的事件处理器,避免重复绑定 $reportList.off('click', '.edit-btn'); $reportList.off('click', '.delete-btn'); $reportList.off('click', '.download-btn'); if (reportData.length === 0) { $reportList.html('暂无报告数据,请点击"新增报告"创建'); return; } reportData.forEach(report => { const $card = $( ${report.name} ${report.type} | 生成日期:${report.date} <button class="action-btn download-btn">下载</button> <button class="action-btn edit-btn">编辑</button> <button class="action-btn delete-btn">删除</button> ); $reportList.append($card); }); // 绑定事件 $reportList.on('click', '.edit-btn', function () { const reportId = $(this).closest('.report-card').data('id'); editReport(reportId); }); $reportList.on('click', '.delete-btn', function () { const reportId = $(this).closest('.report-card').data('id'); deleteReport(reportId); }); $reportList.on('click', '.download-btn', function () { const reportId = $(this).closest('.report-card').data('id'); downloadReport(reportId); }); } // 打开模态框 function openModal(isEdit = false, report = null) { $reportForm[0].reset(); $logTimeRange.hide(); $reportContent.val(''); if (isEdit && report) { $modalTitle.text('编辑报告'); $reportId.val(report.id); $reportName.val(report.name); $reportType.val(report.type); $reportDate.val(report.date); $reportContent.val(report.content); if (report.type === '硬件日志采集报告') { $logTimeRange.show(); $('#log-start-date').val(report.logStartDate || ''); $('#log-end-date').val(report.logEndDate || ''); } } else { $modalTitle.text('新增报告'); $reportId.val(''); $reportDate.val(new Date().toISOString().split('T')[0]); } $reportModal.show(); } // 关闭模态框 function closeModal() { $reportModal.hide(); } // 编辑报告 function editReport(id) { console.log('编辑报告:', reports); console.log('报告ID:', id); const stringId = String(id); const report = reports.find(r => r.id === stringId); console.log('编辑报告:', report); // console.log(r.id); if (report) { openModal(true, report); } else { alert('未找到该报告'); loadReports(); } } // 删除报告 function deleteReport(id) { const stringId = String(id); const report = reports.find(r => r.id === stringId); if (!report) { alert('未找到该报告'); loadReports(); return; } if (confirm(确定要删除"${report.name}"这份报告吗?删除后无法恢复!)) { $.ajax({ url: 'api/reports.php', method: 'DELETE', contentType: 'application/json', data: JSON.stringify({ id: id }), dataType: 'json', success: function (response) { if (response.success) { loadReports(); // 重新加载数据 } else { alert('删除失败:' + (response.message || '未知错误')); } }, error: function (xhr, status, error) { console.error('删除报告失败:', error); alert('删除报告失败,请检查网络连接'); } }); } } // 下载单个报告 function downloadReport(id) { const report = reports.find(r => r.id === id); if (!report) return; let content = 报告名称:${report.name} 报告类型:${report.type} 生成日期:${report.date} 报告内容: ${report.content} .trim(); if (report.type === '硬件日志采集报告' && report.attachments && report.attachments.length) { content += \n\n=== 日志附件 ===\n; report.attachments.forEach(attach => { content += \n【附件:${attach.filename}】\n${attach.content}\n; }); } const blob = new Blob([content], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = $('').attr({ href: url, download: ${report.name.replace(/[\/:*?"<>|]/g, '-')}.txt }); $('body').append(a); a[0].click(); a.remove(); URL.revokeObjectURL(url); } // 下载全部报告 function downloadAllReports() { if (reports.length === 0) { alert('没有报告可下载'); return; } let allContent = '=== 所有报告汇总 ===\n\n'; reports.forEach((report, idx) => { allContent += 【报告 ${idx + 1}】\n; allContent += 名称:${report.name}\n类型:${report.type}\n日期:${report.date}\n\n; allContent += 内容:\n${report.content}\n\n; if (report.type === '硬件日志采集报告' && report.attachments && report.attachments.length) { allContent += === 日志附件 ===\n; report.attachments.forEach(attach => { allContent += \n【附件:${attach.filename}】\n${attach.content}\n; }); } allContent += '========================================\n\n'; }); const blob = new Blob([allContent], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = $('').attr({ href: url, download: 所有报告汇总_${new Date().toISOString().split('T')[0]}.txt }); $('body').append(a); a[0].click(); a.remove(); URL.revokeObjectURL(url); } // 保存报告 $reportForm.on('submit', function (e) { e.preventDefault(); const formData = { id: $reportId.val(), name: $reportName.val(), type: $reportType.val(), date: $reportDate.val(), content: $reportContent.val(), attachments: [] }; if (formData.type === '硬件日志采集报告') { const startDate = $('#log-start-date').val(); const endDate = $('#log-end-date').val(); formData.logStartDate = startDate; formData.logEndDate = endDate; const filteredLogs = hardwareLogs.filter(log => { const logTime = new Date(log.timestamp); const start = new Date(startDate); const end = new Date(endDate); return logTime >= start && logTime <= end; }); if (filteredLogs.length > 0) { const errorCount = filteredLogs.filter(log => log.level === 'ERROR').length; const logSummary = filteredLogs.map(log => [${log.timestamp}] [${log.device}] [${log.level}]:${log.content} ).join('\n'); formData.content = typeTemplates['硬件日志采集报告'] .replace('{startDate}', startDate) .replace('{endDate}', endDate) .replace('{errorCount}', errorCount) .replace('{logSummary}', logSummary); formData.attachments.push({ filename: hardware_logs_${startDate}_${endDate}.txt, content: filteredLogs.map(log => ${log.timestamp}\n${log.device}\n${log.level}\n${log.content}\n-----\n ).join('') }); } else { formData.content = '未找到指定时间段的日志数据'; } } const method = formData.id ? 'PUT' : 'POST'; $.ajax({ url: 'api/reports.php', method: method, contentType: 'application/json', data: JSON.stringify(formData), dataType: 'json', success: function (response) { if (response.success) { loadReports(); closeModal(); } else { alert('保存失败:' + (response.message || '未知错误')); } }, error: function (xhr, status, error) { console.error('保存报告失败:', error); alert('保存报告失败,请检查网络连接'); } }); }); // 搜索报告 function handleSearch() { const keyword = $searchInput.val().toLowerCase(); const filtered = reports.filter(report => report.name.toLowerCase().includes(keyword) || report.type.toLowerCase().includes(keyword) ); renderReports(filtered); } // 按日期排序 function sortReportsByDate() { const sorted = [...reports].sort((a, b) => new Date(b.date) - new Date(a.date) ); renderReports(sorted); } // 事件绑定 function bindEvents() { // 报告类型切换 // / 修改报告类型切换事件 $reportType.on('change', function () { const type = $(this).val(); const $startDate = $('#log-start-date'); const $endDate = $('#log-end-date'); $logTimeRange.hide(); $contentDesc.text('请根据报告类型填写内容...'); if (type === '硬件日志采集报告') { $logTimeRange.show(); $contentDesc.text('选择时间段后将自动生成日志摘要'); $reportContent.val(''); // 仅在日志类型下添加必填属性 $startDate.attr('required', true); $endDate.attr('required', true); } else { $reportContent.val(typeTemplates[type] || ''); // 其他类型下移除必填属性 $startDate.removeAttr('required'); $endDate.removeAttr('required'); } }); // 新增报告 $addReportBtn.on('click', () => openModal()); // 关闭模态框 $closeBtn.on('click', closeModal); $cancelBtn.on('click', closeModal); // 点击模态框外部关闭 $(window).on('click', (e) => { if ($(e.target).is($reportModal)) closeModal(); }); // 搜索 $searchBtn.on('click', handleSearch); $searchInput.on('keypress', (e) => { if (e.key === 'Enter') handleSearch(); }); // 排序 $sortByDateBtn.on('click', sortReportsByDate); // 下载全部 $downloadAllBtn.on('click', downloadAllReports); } // 初始化 function init() { bindEvents(); loadHardwareLogs(); loadReports(); } // 页面加载完成后初始化 $(document).ready(init); </script> </body> </html> 优化代码.让拟态窗更加好看



