如何为动态生成的HTML元素添加无刷新提交的JavaScript事件
动态生成元素的无刷新提交实现方案
问题场景
页面通过AJAX从数据库拉取数据,动态生成商品卡片,需要为每个卡片里的「Add to cart」按钮实现无刷新提交,并调用productList(formId)函数。
原代码存在的问题
- 动态插入的
<script>中使用DOMContentLoaded事件,此时元素已经被添加到DOM,该事件不会触发,导致事件绑定失效 - 事件绑定代码中错误使用
product1而非动态变量product${index},即使事件触发也只会绑定到第一个元素 - 每个商品卡片重复插入
<script>标签,造成代码冗余且维护性差 <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
相关产品推荐
相关产品推荐

