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

函数内动态创建JavaScript对象:多次调用后子对象为空的问题

解决appendDiv多次调用后新创建的子对象为空的问题

我一眼就看出问题出在重复绑定表单submit事件以及DOM选择器的作用范围上,咱们一步步拆解核心问题:

  1. 重复绑定submit事件:每次调用appendDiv,你都会给$('#creates')新增一个submit事件处理函数。当表单最终提交时,所有绑定的处理函数都会依次执行——第一个处理函数里的current_id还是第一次调用时的旧ID,它会继续修改旧对象;而新的处理函数虽然拿着新ID,但因为逻辑冲突,根本没正确给新子对象赋值。

  2. 全局DOM选择器的问题:你用document.querySelectorAll('.period-select')获取的是页面上所有类名为period-select的元素,而不是和当前current_id对应的那一组。如果多次调用appendDiv新增了多组元素,拿到的值会混乱,导致新子对象无法正确赋值。

  3. 变量作用域与初始化时机:你在appendDiv调用时就直接把dataObject[${current_id}]设为空对象,但submit是异步触发的——如果用户调用第二次appendDiv后还没提交表单,新子对象自然是空的;但你说提交后还是空,核心还是前面两个问题导致赋值逻辑没执行。


修复后的代码示例

let dataObject = {};
// 只绑定一次submit事件,避免重复绑定导致的逻辑冲突
$('#creates').submit(function (event) {
    event.preventDefault(); // 必须阻止表单默认提交,否则页面刷新会丢失所有数据
    // 动态获取当前要操作的ID(这里需要你根据实际场景调整,比如从触发元素的标识/自定义属性获取)
    const current_id = event.target.dataset.targetId; // 示例:假设用自定义属性存目标ID
    // 确保子对象存在,避免报错
    if (!dataObject[current_id]) {
        dataObject[current_id] = {};
    }
    const nbrGroupValue = parseInt(document.getElementById('nbr_group').value, 10);
    // 精准选择当前分组下的period-select元素,而非全局所有
    const periodSelects = document.querySelectorAll(`#${current_id} .period-select`);
    const inputList = [];
    for (let j = 0; j < 3; j++) {
        inputList[j] = periodSelects[j].value;
    }
    // 赋值到对应子对象
    for (let i = 0; i < nbrGroupValue; i++) {
        dataObject[current_id][i] = {
            firstvalue: inputList[0],
            secondvalue: inputList[1],
            thirdvalue: inputList[2]
        };
    }
    console.log(dataObject); // 可打印验证结果
});

function appendDiv() {
    const e = event.target;
    const current_id = e.id;
    // 提前初始化子对象(可选,也可以在submit时再做)
    if (!dataObject[current_id]) {
        dataObject[current_id] = {};
    }
    // 这里添加你新增DOM元素的逻辑,比如给表单添加对应分组的period-select
    // 注意要把current_id关联到新增的元素上,比如给表单加data-targetId="${current_id}"
    // ...你的DOM操作代码...
}

关键改进点

  • 单次绑定submit事件:把事件绑定移到appendDiv外部,只执行一次,彻底避免多处理函数冲突的问题。
  • 精准选择DOM元素:通过#${current_id} .period-select限定选择范围,只获取当前分组下的元素,确保值的准确性。
  • 阻止表单默认行为:加上event.preventDefault(),避免页面刷新导致数据丢失,这是表单处理的常见坑。
  • 避免全局变量污染:用const/let声明变量,替代var和全局变量,减少意外的作用域问题。

如果你的场景是每次调用appendDiv会新增独立表单,更推荐用事件委托的方式(绑定到父元素,通过冒泡处理动态新增的表单),灵活性更高:

let dataObject = {};
// 事件委托:绑定到父容器,处理所有动态新增的表单
$('#form-container').on('submit', '.group-form', function (event) {
    event.preventDefault();
    const form = this;
    const current_id = form.dataset.id; // 从表单自定义属性获取ID
    if (!dataObject[current_id]) dataObject[current_id] = {};
    
    const nbrGroupValue = parseInt(form.querySelector('.nbr_group').value, 10);
    const periodSelects = form.querySelectorAll('.period-select');
    const inputList = Array.from(periodSelects).map(el => el.value);
    
    for (let i = 0; i < nbrGroupValue; i++) {
        dataObject[current_id][i] = {
            firstvalue: inputList[0],
            secondvalue: inputList[1],
            thirdvalue: inputList[2]
        };
    }
});

function appendDiv() {
    const e = event.target;
    const current_id = e.id;
    // 创建新表单并关联ID
    const newForm = document.createElement('form');
    newForm.className = 'group-form';
    newForm.dataset.id = current_id;
    // 添加表单元素(nbr_group、period-select等)
    // ...你的DOM构建代码...
    document.getElementById('form-container').appendChild(newForm);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:48:11