繁体   English   中英

选择和取消选择不适用于js中动态创建的复选框

[英]select and unselect not working for dynamically created checkbox in js

我已经使用Bootstrap JS和CSS在Java脚本复选框树中动态创建了。 选择和取消选择无效: 在此处输入图片描述

在第二张图片中是从js动态创建的html: 在此处输入图片描述如果我将其复制并在html中创建,则它可以正常工作。 如何动态创建复选框树?

 $(function() { $('input[type="checkbox"]').change(checkboxChanged); function checkboxChanged() { var $this = $(this), checked = $this.prop("checked"), container = $this.parent(), siblings = container.siblings(); container.find('input[type="checkbox"]') .prop({ indeterminate: false, checked: checked }) .siblings('label') .removeClass('custom-checked custom-unchecked custom-indeterminate') .addClass(checked ? 'custom-checked' : 'custom-unchecked'); checkSiblings(container, checked); } function checkSiblings($el, checked) { var parent = $el.parent().parent(), all = true, indeterminate = false; $el.siblings().each(function() { return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked); }); if (all && checked) { parent.children('input[type="checkbox"]') .prop({ indeterminate: false, checked: checked }) .siblings('label') .removeClass('custom-checked custom-unchecked custom-indeterminate') .addClass(checked ? 'custom-checked' : 'custom-unchecked'); checkSiblings(parent, checked); } else if (all && !checked) { indeterminate = parent.find('input[type="checkbox"]:checked').length > 0; parent.children('input[type="checkbox"]') .prop("checked", checked) .prop("indeterminate", indeterminate) .siblings('label') .removeClass('custom-checked custom-unchecked custom-indeterminate') .addClass(indeterminate ? 'custom-indeterminate' : (checked ? 'custom-checked' : 'custom-unchecked')); checkSiblings(parent, checked); } else { $el.parents("li").children('input[type="checkbox"]') .prop({ indeterminate: true, checked: false }) .siblings('label') .removeClass('custom-checked custom-unchecked custom-indeterminate') .addClass('custom-indeterminate'); } } }); 
 * { margin: 0; padding: 0; } #page-wrap { margin: auto 0; } .treeview { margin: 10px 0 0 20px; } ul { list-style: none; } .treeview li { background: url(http://jquery.bassistance.de/treeview/images/treeview-default-line.gif) 0 0 no-repeat; padding: 2px 0 2px 16px; } .treeview > li:first-child > label { /* style for the root element - IE8 supports :first-child but not :last-child ..... */ } .treeview li.last { background-position: 0 -1766px; } .treeview li > input { height: 16px; width: 16px; /* hide the inputs but keep them in the layout with events (use opacity) */ opacity: 0; filter: alpha(opacity=0); /* internet explorer */ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"; /*IE8*/ } .treeview li > label { background: url(https://www.thecssninja.com/demo/css_custom-forms/gr_custom-inputs.png) 0 -1px no-repeat; /* move left to cover the original checkbox area */ margin-left: -20px; /* pad the text to make room for image */ padding-left: 20px; } /* Unchecked styles */ .treeview .custom-unchecked { background-position: 0 -1px; } .treeview .custom-unchecked:hover { background-position: 0 -21px; } /* Checked styles */ .treeview .custom-checked { background-position: 0 -81px; } .treeview .custom-checked:hover { background-position: 0 -101px; } /* Indeterminate styles */ .treeview .custom-indeterminate { background-position: 0 -141px; } .treeview .custom-indeterminate:hover { background-position: 0 -121px; } 
 <body class="skin-blue sidebar-mini" style="height: auto; min-height: 100%;"> <!-- changing values in row --> <input id="rowNumber" class="form-control " type="hidden"> <div class="wrapper" style="height: auto; min-height: 100%; background-color: #ECEFF4;"> <!-- Main content --> <section class="content"> <div class="row"> <div class="col-xs-12"> <!-- /.box --> <div class="box"> <!-- /.box-header --> <div class="box-body"> <button onclick="addCheckBox()">add</button> <input id="check" name="checkBoxes"> <div id="page-wrap"> <ul class="treeview"> <li> <input type="checkbox" name="short" id="short"> <label for="short" class="custom-unchecked">Short Things</label> <ul id="cc"> </ul> </li> </ul> </div> </div> <!-- /.box-body --> </div> <!-- /.box --> </div> <!-- /.col --> </div> <!-- /.row --> </section> <!-- /.content --> </div> <script src="//code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E=" crossorigin="anonymous"></script> <script type="text/javascript"> function addCheckBox() { var listElement = document.getElementById('cc'); var check_value = new Array(); check_value[1] = "Yellow"; check_value[2] = "Red"; check_value[3] = "Green"; var li, checkbox, label, br, a; var title = document.getElementById('check').value; for (var i = 1; i <= title; i++) { li = document.createElement("li"); if (i == title) { li.className = "last"; } checkbox = document.createElement("input"); checkbox.type = "checkbox"; checkbox.name = "short-" + i; checkbox.id = "short-" + i; label = document.createElement("label"); label.htmlFor = "short-" + i; label.className = "custom-unchecked"; label.setAttribute("class", "custom-unchecked"); label.innerHTML = check_value[i]; li.innerHTML += checkbox.outerHTML + label.outerHTML; listElement.appendChild(li); /*li.appendChild(checkbox); //li.appendChild(label); listElement.appendChild(li); listElement.appendChild(checkbox); listElement.appendChild(label); */ } } </script> </body> 

从代码的角度来看,所有这些都可以正常工作。

  1. 页面加载后,事件附加到创建的DOM元素上
  2. 您可以通过单击添加按钮来添加新的DOM元素。
  3. 因此,您应该分离旧事件(以减少内存泄漏)并创建新事件。

用几句话在创建新元素后在addCheckBox()函数中应该添加:

$('input[type="checkbox"]').off('change'); // detach event
$('input[type="checkbox"]').on('change', checkboxChanged); // add new event

正如@ Alx-lark所说,您遇到的问题是您在初始页面加载时绑定更改事件,但是事件绑定的工作方式是, 以后添加到页面的任何后续复选框元素都不会被绑定。 他的答案中提到的解决方案-在所有复选框上解除绑定,然后在所有复选框(包括最近添加的复选框)上重新绑定,应该可以工作。

您还可以在添加单个复选框时对其进行绑定,或者可以在始终存在的元素(如document上更高的位置进行绑定

这可能是最简单的更改,更改行

$('input[type="checkbox"]').change(checkboxChanged)$(document).on('change', 'input[type="checkbox"]', checkboxChanged);

这称为事件委托 ,您可以在这里阅读有关信息: https : //learn.jquery.com/events/event-delegation/

通过事件委托,我们可以将单个事件侦听器附加到父元素,该元素将为与选择器匹配的所有后代触发,无论这些后代现在存在还是将来添加。

  function checkboxChanged() { var $this = $(this), checked = $this.prop("checked"), container = $this.parent(), siblings = container.siblings(); container.find('input[type="checkbox"]') .prop({ indeterminate: false, checked: checked }) .siblings('label') .removeClass('custom-checked custom-unchecked custom-indeterminate') .addClass(checked ? 'custom-checked' : 'custom-unchecked'); checkSiblings(container, checked); } function checkSiblings($el, checked) { var parent = $el.parent().parent(), all = true, indeterminate = false; $el.siblings().each(function() { return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked); }); if (all && checked) { parent.children('input[type="checkbox"]') .prop({ indeterminate: false, checked: checked }) .siblings('label') .removeClass('custom-checked custom-unchecked custom-indeterminate') .addClass(checked ? 'custom-checked' : 'custom-unchecked'); checkSiblings(parent, checked); } else if (all && !checked) { indeterminate = parent.find('input[type="checkbox"]:checked').length > 0; parent.children('input[type="checkbox"]') .prop("checked", checked) .prop("indeterminate", indeterminate) .siblings('label') .removeClass('custom-checked custom-unchecked custom-indeterminate') .addClass(indeterminate ? 'custom-indeterminate' : (checked ? 'custom-checked' : 'custom-unchecked')); checkSiblings(parent, checked); } else { $el.parents("li").children('input[type="checkbox"]') .prop({ indeterminate: true, checked: false }) .siblings('label') .removeClass('custom-checked custom-unchecked custom-indeterminate') .addClass('custom-indeterminate'); } } $(function() { $(document).on('change', 'input[type="checkbox"]', checkboxChanged); }); 
 * { margin: 0; padding: 0; } #page-wrap { margin: auto 0; } .treeview { margin: 10px 0 0 20px; } ul { list-style: none; } .treeview li { background: url(http://jquery.bassistance.de/treeview/images/treeview-default-line.gif) 0 0 no-repeat; padding: 2px 0 2px 16px; } .treeview > li:first-child > label { /* style for the root element - IE8 supports :first-child but not :last-child ..... */ } .treeview li.last { background-position: 0 -1766px; } .treeview li > input { height: 16px; width: 16px; /* hide the inputs but keep them in the layout with events (use opacity) */ opacity: 0; filter: alpha(opacity=0); /* internet explorer */ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"; /*IE8*/ } .treeview li > label { background: url(https://www.thecssninja.com/demo/css_custom-forms/gr_custom-inputs.png) 0 -1px no-repeat; /* move left to cover the original checkbox area */ margin-left: -20px; /* pad the text to make room for image */ padding-left: 20px; } /* Unchecked styles */ .treeview .custom-unchecked { background-position: 0 -1px; } .treeview .custom-unchecked:hover { background-position: 0 -21px; } /* Checked styles */ .treeview .custom-checked { background-position: 0 -81px; } .treeview .custom-checked:hover { background-position: 0 -101px; } /* Indeterminate styles */ .treeview .custom-indeterminate { background-position: 0 -141px; } .treeview .custom-indeterminate:hover { background-position: 0 -121px; } 
 <body class="skin-blue sidebar-mini" style="height: auto; min-height: 100%;"> <!-- changing values in row --> <input id="rowNumber" class="form-control " type="hidden"> <div class="wrapper" style="height: auto; min-height: 100%; background-color: #ECEFF4;"> <!-- Main content --> <section class="content"> <div class="row"> <div class="col-xs-12"> <!-- /.box --> <div class="box"> <!-- /.box-header --> <div class="box-body"> <button onclick="addCheckBox()">add</button> <input id="check" name="checkBoxes"> <div id="page-wrap"> <ul class="treeview"> <li> <input type="checkbox" name="short" id="short"> <label for="short" class="custom-unchecked">Short Things</label> <ul id="cc"> </ul> </li> </ul> </div> </div> <!-- /.box-body --> </div> <!-- /.box --> </div> <!-- /.col --> </div> <!-- /.row --> </section> <!-- /.content --> </div> <script src="//code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E=" crossorigin="anonymous"></script> <script type="text/javascript"> function addCheckBox() { var listElement = document.getElementById('cc'); var check_value = new Array(); check_value[1] = "Yellow"; check_value[2] = "Red"; check_value[3] = "Green"; var li, checkbox, label, br, a; var title = document.getElementById('check').value; for (var i = 1; i <= title; i++) { li = document.createElement("li"); if (i == title) { li.className = "last"; } checkbox = document.createElement("input"); checkbox.type = "checkbox"; checkbox.name = "short-" + i; checkbox.id = "short-" + i; label = document.createElement("label"); label.htmlFor = "short-" + i; label.className = "custom-unchecked"; label.setAttribute("class", "custom-unchecked"); label.innerHTML = check_value[i]; li.innerHTML += checkbox.outerHTML + label.outerHTML; listElement.appendChild(li); /*li.appendChild(checkbox); //li.appendChild(label); listElement.appendChild(li); listElement.appendChild(checkbox); listElement.appendChild(label); */ } } </script> </body> 

对我来说,我必须在文件之后瞄准容器

$(document).on('change', '.input-container input[class^=open-all]', function(e) {
//console.log(e);
if (e.target !== this)
return;

if ($(this).is(':checked')) {
    //true
    switchStatus = $(this).is(':checked');
}
else {
    // flase
    switchStatus = $(this).is(':checked');
}
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM