You need to enable JavaScript to run this app. 如何使用HTML、JavaScript、jQuery永久追加动态div 避免表单提交后丢失
优惠活动
大模型
产品
解决方案
定价
更多

如何使用HTML、JavaScript、jQuery永久追加动态div 避免表单提交后丢失

问题原因

普通同步表单提交后页面会重新刷新,前端JS动态生成的DOM元素默认不会被服务端渲染到返回的页面里,所以刷新后就会消失。

解决步骤

1. 服务端记录提交的动态项数量

表单提交后,服务端先接收提交的动态字段数组,统计数量,把这个数量和已提交的内容输出到页面的JS变量里,用来做回显:

<?php
// 统计提交的服务项数量,默认最少1个
$serviceCount = isset($_POST['sel_services']) ? count($_POST['sel_services']) : 1;
// 把每个项的提交值也存下来,用来回显
$submittedServices = $_POST['sel_services'] ?? [];
$submittedCare = $_POST['care'] ?? [];
$submittedComments = $_POST['comment'] ?? [];
?>
<script>
// 页面加载时就可以拿到已提交的项数
var existedServiceCount = <?php echo $serviceCount; ?>;
// 也可以把已提交的数据转成JSON给前端用
var submittedData = <?php echo json_encode([
    'services' => $submittedServices,
    'care' => $submittedCare,
    'comments' => $submittedComments
]); ?>;
</script>

2. 页面加载完成后自动渲染已有的动态项

把原来生成DOM的逻辑封装成公共函数,页面加载的时候根据existedServiceCount循环调用,把之前用户添加的项都重新渲染出来,同时处理数据回显:

// 封装生成单个服务项的函数
function createServiceItem(index, prefillData = {}) {
    let szData = '<div class="services-item"><div class="form-group"><div class=" col-xs-12 col-sm-12 col-md-12 col-lg-12">'+
    '<input type="checkbox" name="item_index[]" /><select id="sel_box_'+index+'" name="sel_services[]">';
    // 下拉框回显逻辑
    const serviceOptions = ["Facilities","Housekeeping","Security","Cafeteria","Florist","Delifrance","Pharmacy","Parentcraft Retail","Car"];
    serviceOptions.forEach(opt => {
        const selected = prefillData.services == opt ? 'selected' : '';
        szData += `<option value="${opt}" ${selected}>${opt}</option>`;
    });
    szData += '</select></div>';
    szData += '<label class=" col-xs-12 col-sm-12 col-md-12 col-lg-12">Please rate your experience.</label>'+
    '<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">';
    // 单选框回显逻辑
    const rateOptions = [
        {value: 'Excellent', phpVar: `<?php echo $Others${index}EX ?? '' ?>`},
        {value: 'Good', phpVar: `<?php echo $Others${index}GD ?? '' ?>`},
        {value: 'Fair', phpVar: `<?php echo $Others${index}FA ?? '' ?>`},
        {value: 'Poor', phpVar: `<?php echo $Others${index}PR ?? '' ?>`}
    ];
    rateOptions.forEach(rate => {
        const checked = prefillData.care == rate.value ? 'checked' : rate.phpVar;
        szData += `<label class="radio-inline"><input type="radio" name="care[${index}]" value="${rate.value}" ${checked} >${rate.value}</label>`;
    });
    szData += `<?php echo $errorOthers${index} ?? '' ?></div></div><div class="form-group"><label class=" col-xs-12 col-sm-12 col-md-12 col-lg-12">Areas we do well / Areas needing improvement:</label>`+
    `<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12"><textarea class="col-xs-12 col-sm-12 col-md-12 col-lg-12" id="comment_${index}" name="comment[${index}]" rows="5" >${prefillData.comment ?? ''}</textarea></div></div></div>`;
    $("#services").append(szData);
}

$(document).ready(function() {
    // 页面加载时先渲染已有的项
    let i = existedServiceCount;
    let j = existedServiceCount;
    const max = 10; // 替换成你自己设置的最大添加数量
    for(let k = 0; k < existedServiceCount; k++) {
        // 传入对应下标的预填充数据
        createServiceItem(k, {
            services: submittedData.services[k] ?? '',
            care: submittedData.care[k] ?? '',
            comment: submittedData.comments[k] ?? ''
        });
    }
    // 原来的添加按钮逻辑改成调用封装好的函数
    $("#add_item").on('click',function(){
        if(i < max) {
            createServiceItem(j);
            j++;
            i++;            
        }
    });
});

3. 修复原有代码的遗留问题

  • 动态生成的元素不要用重复id,要给id加上序号后缀,避免DOM选择冲突
  • 原来的PHP变量只处理了第1个项的情况,要改成支持多序号的变量,比如$Others1EX、$Others2EX以此类推

可选简化方案

如果不想改服务端渲染逻辑,可以直接把表单提交改成AJAX异步提交,页面全程不刷新,动态生成的DOM自然就不会丢失。校验失败的话直接在当前页显示错误提示即可,不需要重新加载页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 22:24:03