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

JavaScript点击按钮重复创建自定义属性对象失效问题求解

D&D Initiative 追踪器按钮二次点击失效问题解决及唯一标识实现

核心问题:按钮事件监听丢失

你的代码里,saveCombBtn 放在了 #canvas 容器内部。每次调用 disCombInfo 时,使用 canvas.innerHTML += ... 添加新内容会重新渲染整个 canvas 的所有元素——包括原本的输入框和按钮。重新渲染后,原来绑定了点击事件的按钮被替换成了全新的、未绑定事件的按钮,所以第二次点击完全没有响应。

修复步骤

1. 分离输入区域与显示区域

将输入控件容器移出 #canvas,避免渲染战斗员时影响按钮:

<body>
    <h1>Initiative Tracker</h1>
    <!-- 输入区域独立于显示容器 -->
    <div class="CombInElCont">
        <input id="combNameInEl" placeholder="Combatant Name">
        <input id="combInitModInEl" placeholder="Initiative Modifier" type="Number">
        <button id="saveCombBtn">Save Combatant</button>
    </div>
    <!-- 仅用于显示战斗员的容器 -->
    <div id="canvas"></div>
<script src="script.js"></script>
</body>

2. 优化渲染逻辑

方案A:清空后重新渲染(简单直观)

每次渲染前清空显示容器,再重新生成所有战斗员的展示内容:

function disCombInfo() {
    // 先清空显示容器
    canvas.innerHTML = '';
    for (let i = 0; i < combArray.length; i++) {
        canvas.innerHTML += `
        <div class="combInfoDisp">
            <p>
                Combatant Name:<br>
                ${combArray[i].name}<br>
                Initiative Modifier:<br>
                ${combArray[i].initMod}
                <br>ID: ${combArray[i].id}
            </p>
        </div>
        `;
    };
};

方案B:仅添加新战斗员(性能更优)

直接创建新元素并追加到容器,无需循环整个数组:

function saveCombatant() {
    console.log('saveBtn pressed');
    let combName = combNameInEl.value.trim();
    let combInitMod = combInitModInEl.value;

    // 空名字校验,避免无效数据
    if (!combName) return;

    let newComb = new Combatant(combName, combInitMod);
    combArray.push(newComb);
    
    // 创建新的战斗员展示元素并追加
    const combDiv = document.createElement('div');
    combDiv.className = 'combInfoDisp';
    combDiv.innerHTML = `
        <p>
            Combatant Name:<br>
            ${newComb.name}<br>
            Initiative Modifier:<br>
            ${newComb.initMod}
            <br>ID: ${newComb.id}
        </p>
    `;
    canvas.appendChild(combDiv);

    combNameInEl.value = '';
    combInitModInEl.value = '';
};

给 Combatant 添加唯一标识

方式1:自增ID(连续编号)

定义全局变量记录ID,每次创建对象时自动递增:

let combatantId = 1;
function Combatant(combName, combInitMod) {
    this.id = combatantId++;
    this.name = combName;
    this.initMod = combInitMod;
}

方式2:时间戳ID(无连续要求场景)

利用 Date.now() 生成唯一ID,无需额外变量:

function Combatant(combName, combInitMod) {
    this.id = Date.now();
    this.name = combName;
    this.initMod = combInitMod;
}

额外建议

  • 添加输入校验:比如限制 initiative modifier 为有效数字、禁止空名称,避免无效数据存入数组。
  • 后续可添加按 initiative 排序的功能,更贴合D&D initiative追踪的实际需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:45:39