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

时间:2018-09-24 16:48:27

标签: javascript css twitter-bootstrap

我已经使用bootstrap js和css在java脚本复选框树中动态创建了。选择和取消选择不起作用:enter image description here

第二张图片是从js动态创建的html: enter image description here 如果我将其复制并在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>

3 个答案:

答案 0 :(得分:0)

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

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

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

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

答案 1 :(得分:0)

正如@ 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>

答案 2 :(得分:0)

对我来说,我必须在文档之后定位容器

$(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');
}
});