简体   繁体   English

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

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

I've created dynamically in java script checkbox tree using bootstrap js and css. 我已经使用Bootstrap JS和CSS在Java脚本复选框树中动态创建了。 Select and unselect does not working: enter image description here 选择和取消选择无效: 在此处输入图片描述

In the second picture is the html created dynamically from js: enter image description here If I copy this and create in the html it is working. 在第二张图片中是从js动态创建的html: 在此处输入图片描述如果我将其复制并在html中创建,则它可以正常工作。 How to create dynamically check box tree? 如何动态创建复选框树?

 $(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> 

From code point of view, all works correctly. 从代码的角度来看,所有这些都可以正常工作。

  1. Event attached to created DOM elements after page loaded 页面加载后,事件附加到创建的DOM元素上
  2. You progamarly by clicking on Add button add new DOM elements. 您可以通过单击添加按钮来添加新的DOM元素。
  3. So you should detach old events(to reduce memory leaks) and create new one. 因此,您应该分离旧事件(以减少内存泄漏)并创建新事件。

In few words in your addCheckBox() function after creating new elements you should add: 用几句话在创建新元素后在addCheckBox()函数中应该添加:

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

As @Alx-lark says, The issue you are encountering is that you are binding on change event on initial page load, but the way the event binding works, any subsequent checkbox elements that are added to the page later on will not be bound. 正如@ Alx-lark所说,您遇到的问题是您在初始页面加载时绑定更改事件,但是事件绑定的工作方式是, 以后添加到页面的任何后续复选框元素都不会被绑定。 The solution mentioned in his answer - unbinding on ALL checkboxes and then rebinding on ALL checkboxes, including the ones most recently added, should work. 他的答案中提到的解决方案-在所有复选框上解除绑定,然后在所有复选框(包括最近添加的复选框)上重新绑定,应该可以工作。

You could also bind on the individual checkbox as you add it, OR you could bind higher up on an element that always does exist, like the document 您还可以在添加单个复选框时对其进行绑定,或者可以在始终存在的元素(如document上更高的位置进行绑定

This is probably the easiest change to make, changing the line 这可能是最简单的更改,更改行

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

This is called event delegation and you can read about it here: https://learn.jquery.com/events/event-delegation/ 这称为事件委托 ,您可以在这里阅读有关信息: https : //learn.jquery.com/events/event-delegation/

Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future. 通过事件委托,我们可以将单个事件侦听器附加到父元素,该元素将为与选择器匹配的所有后代触发,无论这些后代现在存在还是将来添加。

  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> 

for me I had to target the container after document 对我来说,我必须在文件之后瞄准容器

$(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