点击按钮弹出表单弹窗问题求助:表单复用及空指针错误修复
问题解决:点击按钮弹出对应产品的弹窗表单
问题概述
- 需要将产品对应的表单改为点击「Uzmi sada」按钮时弹出的弹窗组件
- 当前存在两个核心问题:
- 所有产品点击后弹窗均显示第一个产品的表单内容
- 当
portfolioItem为空时,会触发错误:Cannot read properties of null (reading 'innerHTML')
修复后的代码
JavaScript
document.addEventListener("click", (e) => { if (e.target.classList.contains("take")) { togglePortfolioPopup(); document.querySelector(".portfolio-popup").scrollTo(0, 0); // 定位当前按钮所属的产品容器,而非仅父元素 const portfolioItem = e.target.closest(".shopbox"); portfolioItemDetails(portfolioItem); } }) function togglePortfolioPopup() { const popup = document.querySelector(".portfolio-popup"); popup.classList.toggle("open"); document.body.classList.toggle("hide-scrolling"); } // 修复弹窗关闭逻辑:仅点击遮罩层时关闭弹窗 document.addEventListener("click", (e) => { if (e.target.classList.contains("portfolio-popup")) { togglePortfolioPopup(); } }); function portfolioItemDetails(portfolioItem) { // 空值判断,避免触发报错 if (!portfolioItem) return; const popupHeaderH3 = document.querySelector(".pp-header h3"); const popupHeaderP = document.querySelector(".pp-header p"); const popupBody = document.querySelector(".pp-body"); const naziv = portfolioItem.querySelector(".naziv"); const poeni = portfolioItem.querySelector(".poeni"); const details = portfolioItem.querySelector(".portfolio-item-details"); // 逐个校验元素是否存在后再赋值 if (naziv) popupHeaderH3.innerHTML = naziv.innerHTML; if (poeni) popupHeaderP.innerHTML = poeni.innerHTML; if (details) popupBody.innerHTML = details.innerHTML; };
HTML
(注:仅需确保每个产品的卡片和表单都包裹在.shopbox容器内,示例结构如下)
<!-- 单个产品容器:卡片+表单 --> <div class="shopbox"> <div class="card" id="card1"> <div class="novo">NOVO!</div> <div class="stanje1">Na stanju: <span style="color: gold">2</span></div> <div class="imgBx"> <img src="images/Produkti/battlepass.png"> </div> <div class="contentBx"> <h2 class="naziv">Bs battle pass</h2> <span class="snizenje">18,000 poena</span> <span class="poeni">17,000 poena</span> <button class="take">Uzmi sada</button> </div> </div> <!-- 对应产品的表单 --> <div class="portfolio-item-details"> <section id="porudzbine"> <form action="https://formsubmit.co/shop@tutz.info" method="POST"> <div class="form-row"> <div class="input-data"> <input type="text" name="Ime i Prezime" required> <div class="underline"></div> <label>Ime i Prezime</label> </div> <div class="input-data"> <input type="email" name="Email" required> <div class="underline"></div> <label>Email adresa</label> </div> </div> <!-- 表单其余部分保持原有结构即可 --> <input type="hidden" name="_subject" value="Nova porudzbina: battlepass!"> <input type="hidden" name="_next" value="https://tutz.info/hvala.html"> </form> </section> </div> </div> <!-- 弹窗容器 --> <div class="portfolio-popup"> <div class="pp-inner"> <div class="pp-content"> <div class="pp-header"> <h3></h3> <p></p> <p style="color: red; text-align: center; font-weight: 700"> <i class="fa-solid fa-triangle-exclamation fa-beat-fade" style="color:red"></i> Slanje forme bez dovoljno poena ce biti kaznjeno smanjenjem poena <i class="fa-solid fa-triangle-exclamation fa-beat-fade" style="color:red"></i> </p> </div> <div class="pp-body"></div> </div> </div> </div>
修复说明
- 定位正确的产品容器:使用
closest(".shopbox")精准获取当前按钮所属的产品外层容器,确保弹窗加载对应产品的表单,解决了所有弹窗内容一致的问题 - 添加空值校验:在赋值前判断元素是否存在,彻底避免空值读取的报错
- 优化弹窗关闭逻辑:将关闭触发条件改为点击弹窗遮罩层,防止点击弹窗内部内容时误关闭
内容的提问来源于stack exchange,提问作者Milan_567
相关产品推荐
相关产品推荐

