You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击按钮弹出表单弹窗问题求助:表单复用及空指针错误修复

问题解决:点击按钮弹出对应产品的弹窗表单

问题概述

  • 需要将产品对应的表单改为点击「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>

修复说明

  1. 定位正确的产品容器:使用closest(".shopbox")精准获取当前按钮所属的产品外层容器,确保弹窗加载对应产品的表单,解决了所有弹窗内容一致的问题
  2. 添加空值校验:在赋值前判断元素是否存在,彻底避免空值读取的报错
  3. 优化弹窗关闭逻辑:将关闭触发条件改为点击弹窗遮罩层,防止点击弹窗内部内容时误关闭

内容的提问来源于stack exchange,提问作者Milan_567

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:50:57