事件不会在第一次点击父 Childs 时触发
event not trigger on first click parent Childs
我正在创建包含父子项和子子项的层次结构关系列表,如果我选中父项,则选中所有子项,但我单击“子项”,然后子项将被选中。一切正常,但它在第二次点击时的工作在第一次点击时不起作用。
这是我的 fiddle 示例。
fiddle link 这里 http://jsfiddle.net/fahadsheikh/qdkwy0s7/8/
function changeCategoryStatus(_this, id) {
var main = document.querySelector(".main-checkbox"+id);
var children = document.querySelectorAll(".sub-checkbox"+id);
function toggleCheck() {
var array=[];
children.forEach(child => {
if($(this).prop("checked") == true){
child.checked = child.checked = true
}
else if($(this).prop("checked") == false){
child.checked = child.checked = false
}
array.push(child.value);
})
return array;
}
if(main){
main.addEventListener("click", toggleCheck);
}
//for sub-parent category
var sub_parent = document.querySelector(".sub-parent"+id);
var sub_children = document.querySelectorAll(".sub-checkbox"+id);
function toggleCheck() {
var array=[];
sub_children.forEach(child => {
if($(this).prop("checked") == true){
child.checked = child.checked = true
}
else if($(this).prop("checked") == false){
child.checked = child.checked = false
}
array.push(child.value);
})
return array;
}
if(sub_parent){
sub_parent.addEventListener("click", toggleCheck);
}
var status = $(_this).prop('checked') == true ? 'active' : 'inactive';
$.ajax({
type: 'POST',
url:"{{url('admin/categories-status')}}",
data: {
id: id,
status: status,
_token: "{{ csrf_token() }}"
},
success: function (result) {
$("#status-success").show();
$("#status-success").html(result.success);
setTimeout(function() {
$("#status-success").hide()
}, 3000);
}
});
}
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#banner-message {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
text-align: center;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
#banner-message.alt {
background: #0084ff;
color: #fff;
margin-top: 40px;
width: 200px;
}
#banner-message.alt button {
background: #fff;
color: #000;
}
<div class="sortable">
<div class="group-caption">
<li class="main-parent category-sortable main-item" data-parent="4" data-position="4" data-newposition="1">second room
<span class="buttons-align">
<label class="switch">
<input class="main-checkbox4" type="checkbox" id="user-4"
onclick="changeCategoryStatus(event.target, 4);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move" id="item-move" ><i class="fa fa-bars" aria-hidden="true"></i></div></li>
<ul class="group-items group-items-parent">
<li class="group-item-parent category-sortable" data-parent="5" data-position="1" data-newposition="1">second-child room
<span class="buttons-align">
<label class="switch">
<input class="sub-checkbox4 sub-parent4" type="checkbox" id="user-5"
onclick="changeCategoryStatus(event.target, 5);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div></li>
<ul class="group-items-child">
<li class="group-item-child category-sortable" data-parent="6" data-position="1" data-newposition="0">second subchild
<span class="buttons-align">
<label class="switch">
<input class="sub-checkbox4" type="checkbox" id="user-6"
onclick="changeCategoryStatus(event.target, 6);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div></li>
</ul>
</ul>
</div>
<div class="group-caption">
<li class="main-parent category-sortable main-item" data-parent="7" data-position="4" data-newposition="2">third-room
<span class="buttons-align">
<label class="switch">
<input class="main-checkbox7" type="checkbox" id="user-7"
onclick="changeCategoryStatus(event.target, 7);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move" id="item-move" ><i class="fa fa-bars" aria-hidden="true"></i></div></li>
<ul class="group-items group-items-parent">
<li class="group-item-parent category-sortable" data-parent="9" data-position="1" data-newposition="1">third-child
<span class="buttons-align">
<label class="switch">
<input class="sub-checkbox7 sub-parent7" type="checkbox" id="user-9"
onclick="changeCategoryStatus(event.target, 9);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div></li>
<ul class="group-items-child">
<li class="group-item-child category-sortable" data-parent="10" data-position="1" data-newposition="0">third-subchild
<span class="buttons-align">
<label class="switch">
<input class="sub-checkbox7" type="checkbox" id="user-10"
onclick="changeCategoryStatus(event.target, 10);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div></li>
</ul>
</ul>
</div>
</div>
感谢您的帮助。
您当前逻辑的主要问题是您将 toggleCheck()
函数附加到主复选框 每次单击该复选框时 。这会导致您看到奇怪的行为。
另请注意,您的 HTML 无效。 li
元素只能是 ul
的子元素,不能是 div
的子元素,并且 ul
本身不能是另一个 ul
的子元素。您需要正确构建嵌套列表。您还可以通过删除增量 id 和 class 属性来改进 HTML。它们是一种反模式,会导致比必要的更复杂的代码。使用 DOM 遍历来关联元素。
关于 JS 代码,您应该避免使用内联 onclick
事件处理程序,因为它们不再是好的做法。使用通过 JS 逻辑添加的不显眼的事件处理程序。此外,您多次重新定义 toggleCheck()
函数,这是一个很大的代码味道。
综上所述,HTML 和 JS 可以大大简化:
$('.sortable :checkbox').on('change', e => {
let $cb = $(e.target);
let isChecked = $cb.prop('checked');
$cb.closest('li').find(':checkbox').prop('checked', isChecked);
/*
// AJAX commented out for this demo only
$.ajax({
type: 'POST',
url: "{{url('admin/categories-status')}}",
data: {
id: $cb.prop('id'),
status: isChecked ? 'active' : 'inactive',
_token: "{{ csrf_token() }}"
},
success: function(result) {
$("#status-success").html(result.success).show();
setTimeout(function() {
$("#status-success").hide();
}, 3000);
}
});
*/
});
body {
/* background-color: #20262E; */
padding: 20px;
font-family: Helvetica;
}
.move {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<div class="sortable">
<ul class="group-caption">
<li class="main-parent category-sortable main-item" data-parent="4" data-position="4" data-newposition="1">
second room
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="4" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
<ul class="group-items group-items-parent">
<li class="group-item-parent category-sortable" data-parent="5" data-position="1" data-newposition="1">
second-child room
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="5" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
<ul class="group-items-child">
<li class="group-item-child category-sortable" data-parent="6" data-position="1" data-newposition="0">
second subchild
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="6" />
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul class="group-caption">
<li class="main-parent category-sortable main-item" data-parent="7" data-position="4" data-newposition="2">
third-room
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="7" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
<ul class="group-items group-items-parent">
<li class="group-item-parent category-sortable" data-parent="9" data-position="1" data-newposition="1">
third-child
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="9" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
<ul class="group-items-child">
<li class="group-item-child category-sortable" data-parent="10" data-position="1" data-newposition="0">
third-subchild
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="10" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
我正在创建包含父子项和子子项的层次结构关系列表,如果我选中父项,则选中所有子项,但我单击“子项”,然后子项将被选中。一切正常,但它在第二次点击时的工作在第一次点击时不起作用。 这是我的 fiddle 示例。 fiddle link 这里 http://jsfiddle.net/fahadsheikh/qdkwy0s7/8/
function changeCategoryStatus(_this, id) {
var main = document.querySelector(".main-checkbox"+id);
var children = document.querySelectorAll(".sub-checkbox"+id);
function toggleCheck() {
var array=[];
children.forEach(child => {
if($(this).prop("checked") == true){
child.checked = child.checked = true
}
else if($(this).prop("checked") == false){
child.checked = child.checked = false
}
array.push(child.value);
})
return array;
}
if(main){
main.addEventListener("click", toggleCheck);
}
//for sub-parent category
var sub_parent = document.querySelector(".sub-parent"+id);
var sub_children = document.querySelectorAll(".sub-checkbox"+id);
function toggleCheck() {
var array=[];
sub_children.forEach(child => {
if($(this).prop("checked") == true){
child.checked = child.checked = true
}
else if($(this).prop("checked") == false){
child.checked = child.checked = false
}
array.push(child.value);
})
return array;
}
if(sub_parent){
sub_parent.addEventListener("click", toggleCheck);
}
var status = $(_this).prop('checked') == true ? 'active' : 'inactive';
$.ajax({
type: 'POST',
url:"{{url('admin/categories-status')}}",
data: {
id: id,
status: status,
_token: "{{ csrf_token() }}"
},
success: function (result) {
$("#status-success").show();
$("#status-success").html(result.success);
setTimeout(function() {
$("#status-success").hide()
}, 3000);
}
});
}
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#banner-message {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
text-align: center;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
#banner-message.alt {
background: #0084ff;
color: #fff;
margin-top: 40px;
width: 200px;
}
#banner-message.alt button {
background: #fff;
color: #000;
}
<div class="sortable">
<div class="group-caption">
<li class="main-parent category-sortable main-item" data-parent="4" data-position="4" data-newposition="1">second room
<span class="buttons-align">
<label class="switch">
<input class="main-checkbox4" type="checkbox" id="user-4"
onclick="changeCategoryStatus(event.target, 4);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move" id="item-move" ><i class="fa fa-bars" aria-hidden="true"></i></div></li>
<ul class="group-items group-items-parent">
<li class="group-item-parent category-sortable" data-parent="5" data-position="1" data-newposition="1">second-child room
<span class="buttons-align">
<label class="switch">
<input class="sub-checkbox4 sub-parent4" type="checkbox" id="user-5"
onclick="changeCategoryStatus(event.target, 5);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div></li>
<ul class="group-items-child">
<li class="group-item-child category-sortable" data-parent="6" data-position="1" data-newposition="0">second subchild
<span class="buttons-align">
<label class="switch">
<input class="sub-checkbox4" type="checkbox" id="user-6"
onclick="changeCategoryStatus(event.target, 6);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div></li>
</ul>
</ul>
</div>
<div class="group-caption">
<li class="main-parent category-sortable main-item" data-parent="7" data-position="4" data-newposition="2">third-room
<span class="buttons-align">
<label class="switch">
<input class="main-checkbox7" type="checkbox" id="user-7"
onclick="changeCategoryStatus(event.target, 7);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move" id="item-move" ><i class="fa fa-bars" aria-hidden="true"></i></div></li>
<ul class="group-items group-items-parent">
<li class="group-item-parent category-sortable" data-parent="9" data-position="1" data-newposition="1">third-child
<span class="buttons-align">
<label class="switch">
<input class="sub-checkbox7 sub-parent7" type="checkbox" id="user-9"
onclick="changeCategoryStatus(event.target, 9);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div></li>
<ul class="group-items-child">
<li class="group-item-child category-sortable" data-parent="10" data-position="1" data-newposition="0">third-subchild
<span class="buttons-align">
<label class="switch">
<input class="sub-checkbox7" type="checkbox" id="user-10"
onclick="changeCategoryStatus(event.target, 10);"
>
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div></li>
</ul>
</ul>
</div>
</div>
感谢您的帮助。
您当前逻辑的主要问题是您将 toggleCheck()
函数附加到主复选框 每次单击该复选框时 。这会导致您看到奇怪的行为。
另请注意,您的 HTML 无效。 li
元素只能是 ul
的子元素,不能是 div
的子元素,并且 ul
本身不能是另一个 ul
的子元素。您需要正确构建嵌套列表。您还可以通过删除增量 id 和 class 属性来改进 HTML。它们是一种反模式,会导致比必要的更复杂的代码。使用 DOM 遍历来关联元素。
关于 JS 代码,您应该避免使用内联 onclick
事件处理程序,因为它们不再是好的做法。使用通过 JS 逻辑添加的不显眼的事件处理程序。此外,您多次重新定义 toggleCheck()
函数,这是一个很大的代码味道。
综上所述,HTML 和 JS 可以大大简化:
$('.sortable :checkbox').on('change', e => {
let $cb = $(e.target);
let isChecked = $cb.prop('checked');
$cb.closest('li').find(':checkbox').prop('checked', isChecked);
/*
// AJAX commented out for this demo only
$.ajax({
type: 'POST',
url: "{{url('admin/categories-status')}}",
data: {
id: $cb.prop('id'),
status: isChecked ? 'active' : 'inactive',
_token: "{{ csrf_token() }}"
},
success: function(result) {
$("#status-success").html(result.success).show();
setTimeout(function() {
$("#status-success").hide();
}, 3000);
}
});
*/
});
body {
/* background-color: #20262E; */
padding: 20px;
font-family: Helvetica;
}
.move {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<div class="sortable">
<ul class="group-caption">
<li class="main-parent category-sortable main-item" data-parent="4" data-position="4" data-newposition="1">
second room
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="4" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
<ul class="group-items group-items-parent">
<li class="group-item-parent category-sortable" data-parent="5" data-position="1" data-newposition="1">
second-child room
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="5" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
<ul class="group-items-child">
<li class="group-item-child category-sortable" data-parent="6" data-position="1" data-newposition="0">
second subchild
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="6" />
<span class="slider round"></span>
</label>
</span>
<div class="move"><i class="fa fa-bars" aria-hidden="true"></i></div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul class="group-caption">
<li class="main-parent category-sortable main-item" data-parent="7" data-position="4" data-newposition="2">
third-room
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="7" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
<ul class="group-items group-items-parent">
<li class="group-item-parent category-sortable" data-parent="9" data-position="1" data-newposition="1">
third-child
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="9" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
<ul class="group-items-child">
<li class="group-item-child category-sortable" data-parent="10" data-position="1" data-newposition="0">
third-subchild
<span class="buttons-align">
<label class="switch">
<input type="checkbox" id="10" />
<span class="slider round"></span>
</label>
</span>
<div class="move">
<i class="fa fa-bars" aria-hidden="true"></i>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>