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

动态生成的表单提交按钮JavaScript失效问题求助

动态生成表单提交无响应问题解决

问题说明

页面初始存在的表单可正常提交,但通过JavaScript动态生成的表单点击提交按钮<button type="submit" class="generate-btn">Generate IA</button>时无任何响应。

动态生成表单的代码:

segundoDiv.innerHTML = '';

var nuevoElemento = document.createElement('section');
nuevoElemento.className = 'image-generator';
nuevoElemento.innerHTML = `
        <div class="content">
            <form action="#" class="generate-form">
                <input class="prompt-input" type="text" placeholder="Describe what you want to see" required>
                <div class="controls">
                    <button type="submit" class="generate-btn">Generate IA</button>
                </div>
            </form>
        </div>
        <section class="image-gallery">
            <div class="img-card hiddenia"><img src="images/img-1.jpg" alt="image"></div>
        </section>`;

// Agregar el nuevo elemento dentro del segundo div
segundoDiv.appendChild(nuevoElemento);

原脚本代码(未执行):

const generateForm = document.querySelector(".generate-form");
const generateBtn = generateForm.querySelector(".generate-btn");
const imageGallery = document.querySelector(".image-gallery");

const OPENAI_API_KEY = "12345678910"; // Your OpenAI API key here
let isImageGenerating = false;

const updateImageCard = (imgDataArray) => {
  imgDataArray.forEach((imgObject, index) => {
    const imgCard = imageGallery.querySelectorAll(".img-card")[index];
    const imgElement = imgCard.querySelector("img");
    const downloadBtn = imgCard.querySelector(".download-btn");
        imgCard.classList.remove("hidden");

    // Set the image source to the AI-generated image data
    const aiGeneratedImage = `data:image/jpeg;base64,${imgObject.b64_json}`;
    imgElement.src = aiGeneratedImage;
    
    // When the image is loaded, remove the loading class and set download attributes
    imgElement.onload = () => {
      imgCard.classList.remove("loading");
      downloadBtn.setAttribute("href", aiGeneratedImage);
      downloadBtn.setAttribute("download", `${new Date().getTime()}.jpg`);
    }
  });
}

const generateAiImages = async (userPrompt, userImgQuantity) => {
  try {
    // Send a request to the OpenAI API to generate images based on user inputs
    const response = await fetch("https://api.openai.com/v1/images/generations", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${OPENAI_API_KEY}`,
      },
      body: JSON.stringify({
        prompt: userPrompt,
        n: 1,
        size: "1024x1024",
        response_format: "b64_json"
        
      }),
    });

    // Throw an error message if the API response is unsuccessful
    if(!response.ok) throw new Error("Failed to generate AI images. Make sure your API key is valid.");

    const { data } = await response.json(); // Get data from the response
    updateImageCard([...data]);
  } catch (error) {
    alert(error.message);
  } finally {
    generateBtn.removeAttribute("disabled");
    generateBtn.innerText = "Generate";
    isImageGenerating = false;
  }
}

const handleImageGeneration = (e) => {
  e.preventDefault();
  if(isImageGenerating) return;

  // Get user input and image quantity values
  const userPrompt = e.srcElement[0].value;
  const userImgQuantity = 1;
  
  // Disable the generate button, update its text, and set the flag
  generateBtn.setAttribute("disabled", true);
  generateBtn.innerText = "Generating";
  isImageGenerating = true;
  
  // Creating HTML markup for image cards with loading state
  const imgCardMarkup = Array.from({ length: userImgQuantity }, () => 
      `<div class="img-card loading">
        <img src="images/loader.svg" alt="AI generated image">
        <a class="download-btn" href="#">
          <img src="images/download.svg" alt="download icon">
        </a>
      </div>`
  ).join("");

  imageGallery.innerHTML = imgCardMarkup;
  generateAiImages(userPrompt, userImgQuantity);
}

generateForm.addEventListener("submit", handleImageGeneration);

问题原因

原脚本在页面加载时就执行document.querySelector(".generate-form")获取表单并绑定submit事件,但动态生成的表单此时还未被创建,导致事件只绑定到了页面初始的表单上,新生成的表单没有触发事件的绑定。

同时,原脚本中generateBtn、imageGallery等变量都是页面加载时获取的初始元素,动态生成新表单后,这些变量指向的还是旧元素,无法操作新生成的按钮和图片容器。

解决方案

方法1:使用事件委托(推荐)

将事件绑定到已存在的父元素(比如document或segundoDiv),通过事件冒泡机制监听submit事件,判断触发事件的表单是否是目标动态表单。这种方法无需关心表单何时生成,都能触发事件。

修改原脚本的事件绑定部分,并调整相关函数以适配动态元素:

  1. 替换原有的事件绑定代码:
// 移除原来的 generateForm.addEventListener("submit", handleImageGeneration);
// 改为事件委托
document.addEventListener('submit', function(e) {
  if (e.target.classList.contains('generate-form')) {
    handleImageGeneration(e);
  }
});
  1. 修改handleImageGeneration函数,从事件目标获取当前表单及相关元素:
const handleImageGeneration = (e) => {
  e.preventDefault();
  // 获取当前提交的表单
  const currentForm = e.target;
  const generateBtn = currentForm.querySelector(".generate-btn");
  // 获取当前表单对应的图片容器
  const imageGallery = currentForm.closest('.image-generator').querySelector(".image-gallery");

  if(isImageGenerating) return;

  const userPrompt = currentForm.querySelector(".prompt-input").value;
  const userImgQuantity = 1;
  
  generateBtn.setAttribute("disabled", true);
  generateBtn.innerText = "Generating";
  isImageGenerating = true;
  
  const imgCardMarkup = Array.from({ length: userImgQuantity }, () => 
      `<div class="img-card loading">
        <img src="images/loader.svg" alt="AI generated image">
        <a class="download-btn" href="#">
          <img src="images/download.svg" alt="download icon">
        </a>
      </div>`
  ).join("");

  imageGallery.innerHTML = imgCardMarkup;
  // 将当前按钮和容器作为参数传入
  generateAiImages(userPrompt, userImgQuantity, generateBtn, imageGallery);
}
  1. 修改generateAiImages函数,接收动态元素参数:
const generateAiImages = async (userPrompt, userImgQuantity, generateBtn, imageGallery) => {
  try {
    const response = await fetch("https://api.openai.com/v1/images/generations", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${OPENAI_API_KEY}`,
      },
      body: JSON.stringify({
        prompt: userPrompt,
        n: 1,
        size: "1024x1024",
        response_format: "b64_json"
      }),
    });

    if(!response.ok) throw new Error("Failed to generate AI images. Make sure your API key is valid.");

    const { data } = await response.json();
    // 传入当前图片容器
    updateImageCard([...data], imageGallery);
  } catch (error) {
    alert(error.message);
  } finally {
    generateBtn.removeAttribute("disabled");
    generateBtn.innerText = "Generate";
    isImageGenerating = false;
  }
}
  1. 修改updateImageCard函数,接收图片容器参数:
const updateImageCard = (imgDataArray, imageGallery) => {
  imgDataArray.forEach((imgObject, index) => {
    const imgCard = imageGallery.querySelectorAll(".img-card")[index];
    const imgElement = imgCard.querySelector("img");
    const downloadBtn = imgCard.querySelector(".download-btn");
    imgCard.classList.remove("hidden");

    const aiGeneratedImage = `data:image/jpeg;base64,${imgObject.b64_json}`;
    imgElement.src = aiGeneratedImage;
    
    imgElement.onload = () => {
      imgCard.classList.remove("loading");
      downloadBtn.setAttribute("href", aiGeneratedImage);
      downloadBtn.setAttribute("download", `${new Date().getTime()}.jpg`);
    }
  });
}

方法2:动态生成后绑定事件

在动态生成表单并添加到DOM后,立即获取新表单并绑定submit事件。适合仅单次动态生成表单的场景:

在segundoDiv.appendChild(nuevoElemento);之后添加以下代码:

// 获取新生成的表单
const newGenerateForm = nuevoElemento.querySelector(".generate-form");
// 绑定提交事件
newGenerateForm.addEventListener("submit", handleImageGeneration);

同时,需要修改handleImageGeneration、generateAiImages、updateImageCard函数,确保操作的是当前表单对应的元素(参考方法1中的函数修改逻辑),避免使用页面加载时获取的旧元素变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 11:27:32