同一页面为120款设备创建详情Modal的高效实现方案咨询
问题
当前需要为约120款移动设备各创建一个展示设备详情(图片、维修服务价格等)的Modal,现有单设备Modal的HTML及触发JS代码如下,请问是否存在无需为每个元素创建唯一ID的简便实现方式?
现有单设备Modal HTML代码
<button id="myBtn2">Open Modal</button> <div id="myModal2" class="modal"> <div class="modal-content"> <div class="modal-body"> <div class="left"> <img src="../Apple-iPhone-X-64GB-Silver-4G-Vodafone-Grade-B.png"/> </div> <div class="middle"> <h3 class="Breakge"> Breakge </h3> <div class="hyperclicks"> <p class="click" id="click101" onclick="showhidesector('sector101','click101')">Udskiftning af Skærm</p> <p class="click" id="click20" onclick="showhidesector('sector20','click20')">Udskiftning af Batteri</p> <p class="click" id="click30" onclick="showhidesector('sector30','click30')">Udskiftning af Bagglas</p> </div> </div> <div class="right" id="right2"> <h3 class="Prices"> Prices </h3> <div class="hyperprices"> <div class="description"> Place Description Title Here </div> <div class="seperateline"> </div> <div class="sector" id="sector101"> <div class="priceflex"> <p>Original Kvalitet </p><p class="priceitem">2499.99,-</p> </div> <div class="priceflex"> <p>TopKvalitet </p><p class="priceitem">1399.99,-</p> </div> <div class="priceflex"> <p>KobiKvalitet </p><p class="priceitem">999.99,-</p> </div> </div> <div class="sector" id="sector20"> <div class="priceflex"> <p>Batteri </p><p class="priceitem">649,99,-</p> </div> <div class="priceflex"> <p>TopKvakitet Batteri </p><p class="priceitem">749.99,-</p> </div> </div> <div class="sector" id="sector30"> <div class="priceflex"> <p>Bagglas </p><p class="priceitem">1999.99,-</p> </div> <div class="priceflex"> <p>Bagglas og Ramme </p><p class="priceitem">2699.99,-</p> </div> </div> </div> <div class="btngroup"> <div class="rightbtn"> <input type="button" id="btnClose2" class="btn" value="Close"> </div> </div> </div> </div> <div class="modal-footer"> </div> </div> </div>
现有触发JS代码
var modal2 = document.getElementById("myModal2"); var btn2 = document.getElementById("myBtn2"); var btnClose2 = document.getElementById("btnClose2"); var divState = {}; function showhidesector(id,id2) { if (document.getElementById) { var divid = document.getElementById(id); divState[id] = (divState[id]) ? false : true; for (var div in divState){ if (divState[div] && div != id){ document.getElementById(div).style.display = 'none'; // hide divState[div] = false; } } divid.style.display = (divid.style.display == 'block' ? 'none' : 'block'); } } function activatelink(element) { if(document.getElementById(element.id)) { var btnn=document.getElementById(element.id); btnn.style.color="red"; } } btn2.onclick = function() { modal2.style.display = "block"; } btnClose2.onclick = function() { modal2.style.display = "none"; } window.onclick = function(event) { if (event.target == modal) { modal2.style.display = "none"; } }
解决方案
当然有简便方式,核心思路是复用Modal结构+事件委托+数据驱动,完全不需要为每个元素创建唯一ID,具体实现如下:
1. 复用单个通用Modal模板
只保留一个Modal结构,去掉所有ID,用类名和data-*数据属性标记关键交互点:
<!-- 设备按钮容器,后续可自动生成按钮 --> <div id="device-buttons"></div> <!-- 单个通用Modal --> <div class="modal"> <div class="modal-content"> <div class="modal-body"> <div class="left"> <img class="device-img" src=""/> </div> <div class="middle"> <h3 class="Breakge">Breakge</h3> <div class="hyperclicks"> <p class="click" data-sector="screen">Udskiftning af Skærm</p> <p class="click" data-sector="battery">Udskiftning af Batteri</p> <p class="click" data-sector="backglass">Udskiftning af Bagglas</p> </div> </div> <div class="right"> <h3 class="Prices">Prices</h3> <div class="hyperprices"> <div class="description"></div> <div class="seperateline"></div> <div class="sector" data-sector="screen"> <div class="priceflex"> <p>Original Kvalitet </p><p class="priceitem"></p> </div> <div class="priceflex"> <p>TopKvalitet </p><p class="priceitem"></p> </div> <div class="priceflex"> <p>KobiKvalitet </p><p class="priceitem"></p> </div> </div> <div class="sector" data-sector="battery"> <div class="priceflex"> <p>Batteri </p><p class="priceitem"></p> </div> <div class="priceflex"> <p>TopKvakitet Batteri </p><p class="priceitem"></p> </div> </div> <div class="sector" data-sector="backglass"> <div class="priceflex"> <p>Bagglas </p><p class="priceitem"></p> </div> <div class="priceflex"> <p>Bagglas og Ramme </p><p class="priceitem"></p> </div> </div> </div> <div class="btngroup"> <div class="rightbtn"> <input type="button" class="btn close-modal-btn" value="Close"> </div> </div> </div> </div> <div class="modal-footer"></div> </div> </div>
2. 集中存储所有设备数据
把120款设备的图片、维修价格等信息放在一个JS对象里,方便统一管理:
const deviceData = { "iphone-x": { imgSrc: "../Apple-iPhone-X-64GB-Silver-4G-Vodafone-Grade-B.png", description: "iPhone X 维修服务", prices: { screen: { "Original Kvalitet": "2499.99,-", "TopKvalitet": "1399.99,-", "KobiKvalitet": "999.99,-" }, battery: { "Batteri": "649,99,-", "TopKvakitet Batteri": "749.99,-" }, backglass: { "Bagglas": "1999.99,-", "Bagglas og Ramme": "2699.99,-" } } }, "samsung-s20": { imgSrc: "../Samsung-Galaxy-S20-128GB-Gray-5G-Unlocked-Grade-A.png", description: "Samsung S20 维修服务", prices: { screen: { "Original Kvalitet": "2999.99,-", "TopKvalitet": "1799.99,-" }, battery: { "Batteri": "699,99,-" } } }, // 更多设备数据... };
3. 用事件委托实现所有交互逻辑
不需要给每个按钮单独绑定事件,只需要绑定一次事件监听,通过event.target判断触发元素:
const modal = document.querySelector('.modal'); const modalImg = modal.querySelector('.device-img'); const modalDesc = modal.querySelector('.description'); const priceSectors = modal.querySelectorAll('.sector'); const closeBtn = modal.querySelector('.close-modal-btn'); const buttonContainer = document.getElementById('device-buttons'); // 自动生成所有设备按钮 Object.keys(deviceData).forEach(deviceId => { const btn = document.createElement('button'); btn.className = 'open-modal-btn'; btn.dataset.deviceId = deviceId; btn.textContent = `${deviceId.replace('-', ' ')} 维修价格`; buttonContainer.appendChild(btn); }); // 打开Modal事件委托 document.addEventListener('click', function(e) { if (e.target.classList.contains('open-modal-btn')) { const deviceId = e.target.dataset.deviceId; const device = deviceData[deviceId]; // 填充Modal数据 modalImg.src = device.imgSrc; modalDesc.textContent = device.description; // 填充价格信息 priceSectors.forEach(sector => { const sectorKey = sector.dataset.sector; const priceItems = sector.querySelectorAll('.priceitem'); const pricePairs = Object.entries(device.prices[sectorKey]); priceItems.forEach((item, index) => { item.textContent = pricePairs[index][1]; }); // 默认只显示第一个维修项价格 sector.style.display = sectorKey === 'screen' ? 'block' : 'none'; }); // 显示Modal modal.style.display = 'block'; } }); // 维修项切换事件委托 modal.querySelector('.hyperclicks').addEventListener('click', function(e) { if (e.target.classList.contains('click')) { const targetSector = e.target.dataset.sector; // 切换价格区块显示状态 priceSectors.forEach(sector => { sector.style.display = sector.dataset.sector === targetSector ? 'block' : 'none'; }); // 高亮当前点击的维修项 this.querySelectorAll('.click').forEach(item => { item.style.color = item === e.target ? 'red' : 'inherit'; }); } }); // 关闭Modal逻辑 closeBtn.addEventListener('click', function() { modal.style.display = 'none'; }); window.addEventListener('click', function(e) { if (e.target === modal) { modal.style.display = 'none'; } });
这种方式下,新增设备只需要在deviceData里添加对应数据即可,完全不需要重复编写Modal结构和事件绑定代码,也不需要任何唯一ID。
内容的提问来源于stack exchange,提问作者Salim Al-Tarsha
相关产品推荐
相关产品推荐

