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

如何为动态生成的HTML元素添加无刷新提交的JavaScript事件

动态生成元素的无刷新提交实现方案

问题场景

页面通过AJAX从数据库拉取数据,动态生成商品卡片,需要为每个卡片里的「Add to cart」按钮实现无刷新提交,并调用productList(formId)函数。

原代码存在的问题

  1. 动态插入的<script>中使用DOMContentLoaded事件,此时元素已经被添加到DOM,该事件不会触发,导致事件绑定失效
  2. 事件绑定代码中错误使用product1而非动态变量product${index},即使事件触发也只会绑定到第一个元素
  3. 每个商品卡片重复插入<script>标签,造成代码冗余且维护性差
  4. <div>标签重复定义class属性(class="container"和class="product"),不符合HTML规范

修复方案1:修正原有绑定逻辑

直接在生成元素后绑定事件,无需额外插入<script>:

function getWidgets(){
    
    var listUrl = base_url + widgetsPath + url_auth;
    
    console.log("Sending GET to " + listUrl);
    
    function getSuccess(obj){
        var dataWidget = obj.data;

        for (let i=0; i< dataWidget.length; i++){

            var id = dataWidget[i].id;
            var description = dataWidget[i].description;
            var price = dataWidget[i].pence_price;
            var url = dataWidget[i].url;
            var index = i;
            
            console.log("index: ",i);
            console.log(dataWidget[i].id);
            console.log(dataWidget[i].description);
            console.log(dataWidget[i].pence_price);
            console.log(dataWidget[i].url);
            console.log(" ");

            // 修复div的class属性,合并为一个
            var template =`<!-- product -->
            <div class="container product" id="productId_${index}">
                <form action="" class="product-form">
                    <img src="${url}"></img>
                    <p class="product_Description">${description}</p>
                    <input type="hidden" class="productId" value=${id}>
                    <input type="hidden" class="price" value="0.${price}">
                    <label for="quantity">Quantity:</label>
                    <input type="number" class="quantity" value="1" min="1">
                    <button class="submit">Add to cart</button>
                </form>
            </div>
            <!-- END product -->`

            // 先插入模板
            $("#widgetContainer").append(template);
            // 直接获取刚插入的元素,绑定submit事件
            $(`#productId_${index} .product-form`).on('submit', function(e){
                e.preventDefault();
                var formId = `productId_${index}`;
                productList(formId);
            });

        }
        console.log("success");
        console.log(dataWidget);
        
    };
    
    $.ajax(listUrl, {type: "GET", data: {},success: getSuccess });
};

getWidgets();

修复方案2:使用事件委托(更优)

利用事件冒泡特性,只给父容器绑定一次事件,无需为每个动态元素单独绑定,性能更好:

function getWidgets(){
    
    var listUrl = base_url + widgetsPath + url_auth;
    
    console.log("Sending GET to " + listUrl);
    
    // 提前给父容器绑定事件委托
    $("#widgetContainer").on('submit', '.product-form', function(e){
        e.preventDefault();
        // 获取当前form所在的product div的id
        var formId = $(this).closest('.product').attr('id');
        productList(formId);
    });
    
    function getSuccess(obj){
        var dataWidget = obj.data;

        for (let i=0; i< dataWidget.length; i++){

            var id = dataWidget[i].id;
            var description = dataWidget[i].description;
            var price = dataWidget[i].pence_price;
            var url = dataWidget[i].url;
            var index = i;
            
            console.log("index: ",i);
            console.log(dataWidget[i].id);
            console.log(dataWidget[i].description);
            console.log(dataWidget[i].pence_price);
            console.log(dataWidget[i].url);
            console.log(" ");

            var template =`<!-- product -->
            <div class="container product" id="productId_${index}">
                <form action="" class="product-form">
                    <img src="${url}"></img>
                    <p class="product_Description">${description}</p>
                    <input type="hidden" class="productId" value=${id}>
                    <input type="hidden" class="price" value="0.${price}">
                    <label for="quantity">Quantity:</label>
                    <input type="number" class="quantity" value="1" min="1">
                    <button class="submit">Add to cart</button>
                </form>
            </div>
            <!-- END product -->`

            $("#widgetContainer").append(template);

        }
        console.log("success");
        console.log(dataWidget);
        
    };
    
    $.ajax(listUrl, {type: "GET", data: {},success: getSuccess });
};

getWidgets();

关键改进点

  • 移除冗余的<script>标签,避免重复绑定逻辑
  • 修复HTML属性错误(合并重复的class属性)
  • 事件委托方案减少事件绑定次数,提升页面性能,尤其在商品数量较多时更明显
  • 确保事件能正确绑定到所有动态生成的元素上,实现无刷新提交并调用目标函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:28:11