首页 > 解决方案 > 使用 JS 生成 HTML 元素列表。addEventListener 仅适用于最后一个元素

问题描述

我编写了以下 HTML。这个想法是我可以将项目添加到顶部的列表中,然后生成一个包含名称、复选框和文本字段的字段。文本字段将根据复选框启用/禁用。在我的 javascript 中,切换功能被分配给复选框字段的 onclick 属性,但它仅适用于列表中的最后一项。谁能说出为什么没有将这个功能分配给所有复选框?如果您在浏览器中打开生成的 html 代码,除了最后一个复选框之外,它不会显示任何复选框的 onclick 事件,因此它似乎没有被添加。当我将它分配给下一个时,它是否会以某种方式从前一个中删除?我将如何解决它?谢谢你。

<!DOCTYPE html>
<html>

<body onload="loadAllSettings()" }>
    <script>
        var genOptFields = ["genField1", "genField2"];

        function loadAllSettings() {
            loadSettingsList("genSet", genOptFields);
        }
    </script>
    <h2>Options</h2>

    <form>
        <fieldset id="genSet">
            <legend>General</legend>
        </fieldset>
    </form>


    <script>

        function loadSettingsList(parentId, optionalFields) {
            var fieldset = document.getElementById(parentId);
            for (fieldId of optionalFields) {
                var p = document.createElement('p');

                p.append(fieldId + ":");

                var input = document.createElement('input');
                input.type = "text";
                input.disabled = true;
                input.id = fieldId;

                var cb = document.createElement('input');
                cb.type = "checkbox";
                cb.id = "cb_" + fieldId;
                cb.addEventListener("click", function () {
                    toggleCheck(fieldId);
                });

                p.appendChild(cb);
                p.appendChild(input);

                fieldset.appendChild(p);
            }
        }
        function toggleCheck(fieldId) {
            document.getElementById(fieldId).disabled = !document.getElementById("cb_" + 
            fieldId).checked;
        }
    </script>

</body>

</html>

标签: javascripthtml

解决方案


如下所述,您的 fieldId 引用不是静态的。结果,在调用切换检查时,它总是传递 fieldId 包含的最后一个值,无论如何(通过控制台仔细检查。记录您的 fieldId 传递给切换检查)

function loadAllSettings() {
  const genOptFields = ["genField1", "genField2"];
  loadSettingsList("genSet", genOptFields);
}
function loadSettingsList(parentId, optionalFields) {
    const fieldset = document.getElementById(parentId);
    optionalFields.forEach(function (fieldId) {
      createParagraph(fieldId, fieldset);
    });
}
function createParagraph(fieldId, fieldset) {
  const p = document.createElement('p');
  p.append(fieldId + ":");
  createCheckbox(p, fieldId);
  createInputField(p, fieldId);
  fieldset.appendChild(p);
}
function createInputField(p, fieldId) {
  const input = document.createElement('input');
  input.type = "text";
  input.disabled = true;
  input.id = fieldId;
  p.appendChild(input);
}
function createCheckbox(p, fieldId) {
  const cb = document.createElement('input');
  cb.type = "checkbox";
  cb.id = "cb_" + fieldId;
  //set this attribute to capture value
  cb.setAttribute('data-fieldId', fieldId);
  cb.addEventListener("click", function () {
    //use static data attribute value instead of fieldId var which isnt static
      toggleCheck(this.getAttribute('data-fieldId'));
  });
  p.appendChild(cb);
}
function toggleCheck(fieldId) {
    document.getElementById(fieldId).disabled = !document.getElementById("cb_" + fieldId).checked;
}
<!DOCTYPE html>
<html>

<body onload="loadAllSettings()" }>
    <h2>Options</h2>

    <form>
        <fieldset id="genSet">
            <legend>General</legend>
        </fieldset>
    </form>
</body>

</html>


推荐阅读