jquery 无法检测动态生成的复选框的更改

ngynwnxp  于 6个月前  发布在  jQuery
关注(0)|答案(3)|浏览(95)

说明:

我遇到了一个问题,动态生成的复选框在点击时不会触发更改事件。为了解决这个问题,我使用了$(document).on("change", ".integration-event-checkbox", ...)进行事件委托。虽然这成功地附加了事件,但我在尝试检索选中的复选框并动态更新URL时遇到了问题。
下面是代码的简化版本(副本不是实际代码):HTML文件(index.html):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Multiple Choice Question with URL</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<body>

  <h2>Which events would you like to include in the URL?</h2>

  <form id="checkboxes">
    <label>
      <input type="checkbox" name="optionA" value="A" > A
    </label>
    <br>

    <label>
      <input type="checkbox" name="optionB" value="B" > B
    </label>
    <br>

    <label>
      <input type="checkbox" name="optionC" value="C" > C
    </label>
    <br>

    <label>
      <input type="checkbox" name="optionD" value="D" > D
    </label>
    <br>

    <label for="url">URL:</label>
    <input type="text" id="url" name="url" value="xyz.com" readonly>
  </form>

 <script src="script.js"></script>

</body>
</html>

字符串

JavaScript文件(script.js):

$(document).ready(function() {
    const $checkboxes = $("#checkboxes");
    const integration = [ {all:["push","pull"]},{all:["post","get"]},{all:["put","delete"]}]
    const $eventCheckboxes = $(".integration-event-checkbox");

    // This event handler is not being triggered for dynamically generated checkboxes
    // $(document).on("change", ".integration-event-checkbox", (e) => {
    //     console.warn("Checkbox changed");
    //     console.warn("event",e);
    //     update_url();
    //     e.preventDefault();
    //     e.stopPropagation();
    // });

    const events = display_box(integration[0].all)
    $checkboxes.html(events);

    function display_box(integration){
      const checkboxesHTML = integration.map(item => `
          <label>
              <input type="checkbox" class="integration-event-checkbox" value="${item}" />
              ${item}
          </label>
      `).join('');

          return checkboxesHTML;
    }

    function update_url() {
        const selectedEvents = $eventCheckboxes.filter(":checked").map(function () {
            return this.value;
        }).get().join(",");
        console.log("SELECTED EVENTS: ", selectedEvents);
        // Add the checked events to the URL
        const eventsParam = selectedEvents.length > 0 ? `&events=${selectedEvents}` : '';
        console.log("Events Param: ", eventsParam);

        console.log("event checkboxes: ", $eventCheckboxes);
    }
});

发行详情:

  1. $(document).on("change", ".integration-event-checkbox", ...)事件处理程序未捕获动态生成的复选框的更改。
    1.当尝试使用$eventCheckboxes.filter(":checked").map(...)检索选中的复选框时,selectedEvents$eventCheckboxes集合都为空。

复制步骤:

1.使用JavaScript动态生成复选框。
1.使用$(document).on("change", ".integration-event-checkbox", ...)附加更改事件。
1.单击动态生成的复选框并观察缺少更改事件触发的情况。
1.尝试使用$eventCheckboxes.filter(":checked").map(...)检索选中的复选框,注意结果为空。

预期行为:

应该为动态生成的复选框触发更改事件,并且代码应该正确地检索和显示选中的复选框。
我尝试用let代替const重新初始化$iec变量来解决这个问题,我尝试在重新初始化点上下移动代码,目的是确保变量正确捕获动态生成的复选框。

预期行为:

应该为动态生成的复选框触发更改事件,并且代码应该正确地检索和显示选中的复选框。

agyaoht7

agyaoht71#

如果你使用FormData() constructor,你只能从表单中得到相关的值,如果你过滤了名为“event”的条目,你就得到了相应的值。

const integration = [{
  all: ["push", "pull"]
}, {
  all: ["post", "get"]
}, {
  all: ["put", "delete"]
}];

document.addEventListener('DOMContentLoaded', e => {
  let form = document.forms.form01;
  form.addEventListener('change', update_url);

  form.checkboxes.innerHTML = display_box(integration[0].all);
});

function display_box(integration) {
  const checkboxesHTML = integration.map(item => `
          <label>
              <input type="checkbox" name="event" class="integration-event-checkbox" value="${item}" />
              ${item}
          </label>
      `).join('');

  return checkboxesHTML;
}

function update_url(e) {
  let form = e.target.form;
  let formdata = new FormData(form);
  let selectedEvents = [...formdata]
                          .filter(entry => entry[0] == 'event')
                          .flatMap(event => event[1]).join(',');
  console.log("SELECTED EVENTS: ", selectedEvents);
  let url = new URL(form.url.value);
  let params = new URLSearchParams(url.search);
  params.set('events', selectedEvents);
  form.url.value = url.origin + url.pathname + '?' + params.toString();
}
fieldset {
  border: none;
}
<h2>Which events would you like to include in the URL?</h2>

<form name="form01">
  <fieldset name="checkboxes">
    <label>
      <input type="checkbox" name="optionA" value="A" > A
    </label>
    <br>
    <label>
      <input type="checkbox" name="optionB" value="B" > B
    </label>
    <br>
    <label>
      <input type="checkbox" name="optionC" value="C" > C
    </label>
    <br>
    <label>
      <input type="checkbox" name="optionD" value="D" > D
    </label>
  </fieldset>
  <br>
  <label for="url">URL:</label>
  <input type="text" id="url" name="url" value="https://example.com" readonly>
</form>
9o685dep

9o685dep2#

您可以通过更改来修复它:

const selectedEvents = $eventCheckboxes.filter(":checked").map(function () {
  return this.value;
}).get().join(",");

字符串
收件人:

const selectedEvents = $(".integration-event-checkbox").filter(":checked").map(function () {
  return this.value;
}).get().join(",");


在初始化时,$eventCheckboxes变量还没有动态添加复选框。

3pvhb19x

3pvhb19x3#

而不是用这个

const $eventCheckboxes = $(".integration-event-checkbox");

字符串
jQuery选择器到一个变量只是使用
第一个月
当你在调用update_url()的时候,在代码的顶部用const声明它时,它不包含动态添加的复选框。
我的建议是得到如下复选框

function update_url(){
  selected = new Array();
   $(".integration-event-checkbox").each(function(){
    if ($(this).is(':checked')) selected.push($(this).val())
   })
  let eventParams = new URLSearchParams({ someOtherParam: "test", events: selected.toString(),}).toString()
  console.log(eventParams)
}

相关问题