使动态生成的复选框单击有效,即使单击父div也是如此

时间:2019-01-17 16:25:55

标签: javascript jquery html

我在动态生成的行中有动态生成的复选框。我将委派事件('click')侦听器附加到整行。

一切都很好-我通过单击行中的任何位置来切换复选框状态,只有一件小事-单击复选框本身不会切换其状态。

下面是我的示例代码。有什么想法吗?

//Generate dynamically div row encompassing checkbox and label
$('#wraper').append(`
<div id="row">
	<label>This is the checkbox</label>
  <input type="checkbox"></input>
</div>
<br>
<span class="msg"></span>
`);
//Attach delegated event listener to entire row
$('#wraper').on('click', '#row', function(){
	//Toggle checked attribute
	$('#row [type="checkbox"]').get(0).checked = !$('#row [type="checkbox"]').get(0).checked;
  //Display checked status after click
	$('#wraper .msg').text(`Checkbox status is ${$('#row [type="checkbox"]').get(0).checked}`);
});
<!doctype html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
  <div id="wraper"></div>
</body>
</html>

5 个答案:

答案 0 :(得分:3)

如注释中所述,从代码中删除click逻辑。它会立即覆盖默认的HTML功能。如果您打算即使在单击标签时也要选中复选框,则可以使用for属性并指向复选框的id

更新:如果要选中父项div中任意位置的复选框,请向父项添加click处理程序。如果点击目标不是checkbox,则强制选中该复选框。如果目标是checkbox,则什么也不要做。

$('#wraper').append(`
<div id="row">
	<label>This is the checkbox</label>
  <input type="checkbox"></input>
</div>
<br>
<span class="msg"></span>
`);

$('#wraper').on('click', '#row', function(e) {
  /* If the clicked element is not a checkbox,
      then force the check via jquery
  */
  if (e.target.type !== 'checkbox') {
    $(this).find('input').prop('checked', !$(this).find('input').prop('checked'))
  }
    // Display checked status after click
  $('#wraper .msg').text(`Checkbox status is ${$('#row [type="checkbox"]').get(0).checked}`);
  
});


$("#checkbox-test").change(function() {
  $('#wraper .msg').text(`Checkbox status is ${this.checked}`);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wraper"></div>

答案 1 :(得分:1)

如果单击的元素是复选框,则只需跳过复选框切换。

//Generate dynamically div row encompassing checkbox and label
$('#wraper').append(`
<div id="row">
	<label>This is the checkbox</label>
  <input type="checkbox"></input>
</div>
<br>
<span class="msg"></span>
`);
//Attach delegated event listener to entire row
$('#wraper').on('click', '#row', function(e) {
  var $checkbox = $('#row [type="checkbox"]').eq(0);
  
  //Toggle checked attribute
  if (!$checkbox.is(e.target)) {
    $checkbox.prop('checked', !$checkbox.prop('checked'));
  }
  
  //Display checked status after click
  $('#wraper .msg').text(`Checkbox status is ${$checkbox.prop('checked')}`);
});
<!doctype html>
<html>

<head>
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>

<body>
  <div id="wraper"></div>
</body>

</html>

答案 2 :(得分:0)

不执行任何操作的原因是,如果完全单击复选框,您的代码会立即将其重置为先前的状态。您可以通过使用标签上的for属性来解决此问题-然后仅在复选框本身上使用change事件:

重构的HTML:

<div id="row">
    <label for="checkbox1">This is the checkbox</label>
    <input type="checkbox" id="checkbox1"></input>
</div>

更新的JS:

$("#checkbox1").change(function() {
    $('#wraper .msg').text(`Checkbox status is ${this.checked}`);
}).change(); //execute immediately so the text displays.

答案 3 :(得分:0)

您的主要问题是,当您单击checkbox时,该事件将传播到该行,因此与单击两次复选框相同。解决方案是在单击复选框时将事件stopPropagation()传递给父row

// Generate dynamically div row encompassing checkbox and label

$('#wraper').append(`
    <div id="row">
      <label>This is the checkbox</label>
      <input type="checkbox"></input>
    </div>
    <br>
    <span class="msg"></span>
`);

// Attach delegated event listener to entire row.

$('#wraper').on('click', '#row', function()
{
    // Toggle checked attribute.

    $('#row [type="checkbox"]').get(0).checked = !$('#row [type="checkbox"]').get(0).checked;

    // Display checked status after click.

    $('#wraper .msg').text(`Checkbox status is ${$('#row [type="checkbox"]').get(0).checked}`);
});

$('#wraper').on('click', 'input[type="checkbox"]', function(e)
{
    $('#wraper .msg').text(`Checkbox status is ${$('#row [type="checkbox"]').get(0).checked}`);
    e.stopPropagation();
});
<!doctype html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
  <div id="wraper"></div>
</body>
</html>

答案 4 :(得分:0)

哇!不用担心朋友。一个简单的错误,一旦用户单击了复选框,默认操作就是选中该复选框。您的代码在这里再次执行此“检查”操作。因此,您要立即选中然后取消选中该框!

有两种可能的修复方法供您使用。要么,您可以简单地停止选中/取消选中代码中的复选框,换句话说,在此处注释掉此行:

//$('#row [type="checkbox"]').get(0).checked = !$('#row [type="checkbox"]').get(0).checked;

或者您可以继续这样做,但是您必须使用函数禁用默认的HTML操作

`enter code here`event.preventDefault()

可悲的是,我无法使它与jQuery一起使用...我自己并不十分了解它,但是我敢肯定,其他人会在下面评论如何做到这一点!