如何通过JS根据价格范围与组件选择展示对应弹窗?
问题描述
我正在为项目制作一个网站,用户可选择产品价格范围及组件,提交偏好后需在弹窗中显示对应详情。例如当用户选择$2000价格、item x和item z时,相关产品应在弹窗中展示。但目前无论用户选择何种价格与按钮,始终显示同一个弹窗,尝试过不同JS代码均无效。
问题原因
- 函数重复定义:JS中重复声明了
open__Popup和close__Popup函数,后续定义会覆盖之前的逻辑,导致永远只执行最后定义的弹窗操作。 - 缺少选择判断逻辑:没有根据用户选择的价格范围、组件选项,来动态决定显示对应的弹窗。
解决方案
修改后的HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> test </title> <link rel="stylesheet" href="style.css"> <script src="https://kit.fontawesome.com/3049ab8192.js" crossorigin="anonymous"></script> </head> <body> <!--- slider section ---> <div class="main__1"> <div class="slide__options__container"> <div class="wrapper"> <div class="price-input"> <div class="field"> <span>Min</span> <input type="number" class="input-min" value="2500"> </div> <div class="separator">-</div> <div class="field"> <span>Max</span> <input type="number" class="input-max" value="7500"> </div> </div> <div class="slider"> <div class="progress"></div> </div> <div class="range-input"> <input type="range" class="range-min" min="0" max="10000" value="2500" step="100"> <input type="range" class="range-max" min="0" max="10000" value="7500" step="100"> </div> </div> <h2> pick item 1</h2> <div class="mainbtn__1"> <button type="button" class="btn__001" id="x">item x</button> <button type="button" class="btn__001" id="y">item y</button> </div> <h2> pick item 2 </h2> <div class="mainbtn__2"> <button type="button" class="btn__002" id="e">item e</button> <button type="button" class="btn__002" id="z">item z</button> </div> <div class="popup__container"> <button type="submit" class="popup__btn" onclick="openPopup()">submit</button> <!-- FIRST popup page --> <div class="popup" id="popup"> <table class="table__1" id="tb_1"> <tr> <td>item 1</td> <td>x</td> </tr> <tr> <td>item 2</td> <td>e</td> </tr> <tr> <td>Price</td> <td>$2000</td> </tr> </table> <button type="button" class="close__btn" onclick="closeAllPopups()">Close</button> </div> <!-- second popup page --> <div class="popup" id="popup__2"> <table class="table__2" id="tb_2"> <tr> <td>item 1</td> <td>y</td> </tr> <tr> <td>item 2</td> <td>z</td> </tr> <tr> <td>Price</td> <td>$3000</td> </tr> </table> <button type="button" class="close__btn" onclick="closeAllPopups()">Close</button> </div> </div> </div> </div> <script src="app.js"></script> </body> </html>
注:移除了原HTML中表格标签后多余的语法错误字符,统一弹窗类名以复用样式
修改后的CSS
/* buttons options section*/ .special__1{ background-color: #4837ff; } .special__2{ background-color: #4837ff; } /* pop up page */ .popup__container{ position: relative; text-align:center; } .popup{ display: grid; grid-template-columns: 1fr 1fr; width: 800px; max-width: 800px; background: #FFF; border-radius: 6px; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.1); text-align: center; padding: 0 30px 30px; color: #333; align-items: center; height: 50vh; z-index: 100; visibility: hidden; transition: transform 0.4s ease; } .open-Popup{ visibility: visible; transform: translate(-50%, -50%) scale(1); } .table__1, .table__2{ font-family: arial, sans-serif; width: 100%; height: 50%; background: #fff; border-collapse: collapse; } td, th { border: 1px solid #acacac; text-align: left; padding: 8px; } tr:nth-child(even) { background-color: #dddddd; } .close__btn{ position: relative; width: 50%; margin-top: 20px; left: 80px; background: hsla(204, 100%, 15%, 0.286); color: #fff; border: 0; outline: none; font-size: 18px; border-radius: 4px; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
注:合并弹窗样式,改用fixed定位确保弹窗居中,减少冗余代码
修改后的JS
//slider const rangeInput = document.querySelectorAll(".range-input input"), priceInput = document.querySelectorAll(".price-input input"), range = document.querySelector(".slider .progress"); let priceGap = 1000; priceInput.forEach((input) => { input.addEventListener("input", (e) => { let minPrice = parseInt(priceInput[0].value), maxPrice = parseInt(priceInput[1].value); if (maxPrice - minPrice >= priceGap && maxPrice <= rangeInput[1].max) { if (e.target.className === "input-min") { rangeInput[0].value = minPrice; range.style.left = (minPrice / rangeInput[0].max) * 100 + "%"; } else { rangeInput[1].value = maxPrice; range.style.right = 100 - (maxPrice / rangeInput[1].max) * 100 + "%"; } } }); }); rangeInput.forEach((input) => { input.addEventListener("input", (e) => { let minVal = parseInt(rangeInput[0].value), maxVal = parseInt(rangeInput[1].value); if (maxVal - minVal < priceGap) { if (e.target.className === "range-min") { rangeInput[0].value = maxVal - priceGap; } else { rangeInput[1].value = minVal + priceGap; } } else { priceInput[0].value = minVal; priceInput[1].value = maxVal; range.style.left = (minVal / rangeInput[0].max) * 100 + "%"; range.style.right = 100 - (maxVal / rangeInput[1].max) * 100 + "%"; } }); }); //choices buttons const mainbtnEL_1 = document.querySelectorAll(".btn__001"); const mainbtnEL_2 = document.querySelectorAll(".btn__002"); mainbtnEL_1.forEach(btnEl => { btnEl.addEventListener("click", () => { document.querySelector('.special__1')?.classList.remove('special__1'); btnEl.classList.add('special__1'); }); }); mainbtnEL_2.forEach(btnEl => { btnEl.addEventListener("click", () => { document.querySelector('.special__2')?.classList.remove('special__2'); btnEl.classList.add('special__2'); }); }); //pop up const popup1 = document.getElementById("popup"); const popup2 = document.getElementById("popup__2"); // 获取用户选择的内容 function getUserSelections() { const selectedItem1 = document.querySelector('.btn__001.special__1')?.id || ''; const selectedItem2 = document.querySelector('.btn__002.special__2')?.id || ''; const minPrice = parseInt(priceInput[0].value); const maxPrice = parseInt(priceInput[1].value); return { item1: selectedItem1, item2: selectedItem2, minPrice, maxPrice }; } // 打开对应弹窗 function openPopup() { // 先关闭所有弹窗 closeAllPopups(); const selections = getUserSelections(); // 根据选择判断显示对应弹窗,可根据需求扩展逻辑 if ((selections.item1 === 'x' && selections.item2 === 'e') || (selections.minPrice <= 2000 && selections.maxPrice >= 2000)) { popup1.classList.add('open-Popup'); } else if ((selections.item1 === 'y' && selections.item2 === 'z') || (selections.minPrice <= 3000 && selections.maxPrice >= 3000)) { popup2.classList.add('open-Popup'); } } // 关闭所有弹窗 function closeAllPopups() { popup1.classList.remove('open-Popup'); popup2.classList.remove('open-Popup'); }
注:移除重复函数定义,新增选择获取函数,添加弹窗显示判断逻辑,统一关闭弹窗操作
内容的提问来源于stack exchange,提问作者Ahmed Alkhatib
相关产品推荐
相关产品推荐

