一、原生如何实现全选、小选和反选
1.全选、全不选、反选(低配版)
需求分析:
- 点击全选:设置每一个选择框的
checked为true - 点击全不选:设置每一个选择框的
checked为false - 点击反选:设置每一个选择框的
checked与自身相反
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input id="checkAll" type="button" value="全选" />
<input id="unCheckAll" type="button" value="全不" />
<input id="reverseCheck" type="button" value="反选" />
<br>
<input class="check" type="checkbox" />吃饭
<input class="check" type="checkbox" />睡觉
<input class="check" type="checkbox" />敲代码
<input class="check" type="checkbox" />看书
<input class="check" type="checkbox" />玩魔方
<script>
// 1.获取元素
let checkList = document.querySelectorAll('.check')//获取所有复选框(伪数组)
let checkAll = document.querySelector('#checkAll')//获取全选按钮
let unCheckAll = document.querySelector('#unCheckAll')//获取全不选按钮
let reverseCheck = document.querySelector('#reverseCheck')//获取反选按钮
// 2.注册事件
// 2.1 全选
checkAll.onclick = function () {
// ◆设置每一个选择框的 checked 为 true
for (let i = 0; i < checkList.length; i++) {
checkList[i].checked = true
}
}
//2.2 全不选
unCheckAll.onclick = function () {
// ◆设置每一个选择框的 checked 为 false
for (let i = 0; i < checkList.length; i++) {
checkList[i].checked = false
}
}
//2.3 反选
reverseCheck.onclick = function () {
//3.◆设置每一个选择框的 checked 与自身相反
for (let i = 0; i < checkList.length; i++) {
checkList[i].checked = !checkList[i].checked
}
}
</script>
</body>
</html>
2.全选、反选、小选(高配版)
需求分析:
- 点击全选:设置小选框的
checked值与自身 一致 - 点击反选:设置每一个选择框的
checked与自身相反 - 点击小选: 判断全选的
checked值- 小选框的
checked全部为true,全选才为true - 小选框只要有一个没有勾选就是,全选就是
false
- 小选框的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input id="checkAll" type="checkbox" />全选
<input id="reverseCheck" type="checkbox" />反选
<br>
<input class="check" type="checkbox" />吃饭
<input class="check" type="checkbox" />睡觉
<input class="check" type="checkbox" />敲代码
<input class="check" type="checkbox" />看书
<input class="check" type="checkbox" />玩魔方
<script>
// 1.获取元素
let checkList = document.querySelectorAll('.check')//获取所有复选框(伪数组)
let checkAll = document.querySelector('#checkAll')//获取全选按钮
let reverseCheck = document.querySelector('#reverseCheck')//获取反选按钮
//2.注册事件
//2.1 点击全选
checkAll.onclick = function () {
// ◆设置小选框的 checked 值与自身一致
for (let i = 0; i < checkList.length; i++) {
checkList[i].checked = this.checked
}
}
//2.2 点击反选
reverseCheck.onclick = function () {
// ◆设置每一个选择框的 checked 与自身相反
for (let i = 0; i < checkList.length; i++) {
checkList[i].checked = !checkList[i].checked
}
}
// //2.2 点击小选(法一:累加和思想)
// for (let i = 0; i < checkList.length; i++) {
// checkList[i].onclick = function () {
// // (1)先求选中的总数量
// let sum = 0
// for (let j = 0; j < checkList.length; j++) {
// // 只要有一个勾选了,sum++
// if (checkList[j].checked) {
// sum++
// }
// }
// // (2)判断选中的数量与选择框数量是否一致
// checkAll.checked = (sum === checkList.length)
// }
// }
//2.2 点击小选(法二:开关思想)
for (let i = 0; i < checkList.length; i++) {
checkList[i].onclick = function () {
// (1)声明开关变量
let flag = true
// (2)遍历数组检查开关
for (let i = 0; i < checkList.length; i++) {
// 只要有一个没勾选,flag 就变为 false
if (!checkList[i].checked) {
flag = false
break// ◆中止循环
}
}
// (3)把开关结果赋值给全选的 checked 值
checkAll.checked = flag
}
}
</script>
</body>
</html>
二、使用 vue2 实现全选、小选和反选
<template>
<div>
<label> <input v-model="isAll" type="checkbox" />全选</label>
<label> <input type="checkbox" @change="revCheck" />反选</label><br />
<div v-for="item in list" :key="item.code">
<!-- <input :id="item.code" type="checkbox" v-model="item.state" /><label :for="item.code">{{ item.hobby }}</label> -->
<!-- <label :for="item.code"> <input type="checkbox" :id="item.code">{{item.hobby}}</label> -->
<label><input type="checkbox" v-model="item.state" />{{ item.hobby }}</label>
</div>
</div>
</template>
<script>
export default {
data () {
return {
list: [
{ hobby: '吃饭', code: 1, state: false },
{ hobby: '睡觉', code: 2, state: false },
{ hobby: '敲代码', code: 3, state: true },
{ hobby: '看书', code: 4, state: false },
{ hobby: '玩魔方', code: 5, state: true }
]
}
},
computed: {
isAll: {
// ◆全选影响小选
set (val) {
this.list.forEach((item) => {
item.state = val
})
},
// ◆小选影响全选
get () {
return this.list.every((item) => item.state)
}
}
},
methods: {
// ◆反选影响小选
revCheck () {
this.list.forEach((item) => {
item.state = !item.state
})
}
}
}
</script>
三、使用 vue3 实现全选、小选和反选
<template>
<div>
<label> <input v-model="isAll" type="checkbox" />全选</label>
<label> <input type="checkbox" @change="revCheck" /> 反选</label><br />
<div v-for="item in list" :key="item.code">
<!-- <input :id="item.code" type="checkbox" v-model="item.state" /><label :for="item.code">{{ item.hobby }}</label> -->
<label><input type="checkbox" v-model="item.state" />{{ item.hobby }}</label>
</div>
</div>
</template>
<script>
import { ref, computed } from "vue";
export default {
setup() {
const list = ref([
{ hobby: '吃饭', code: 1, state: false },
{ hobby: '睡觉', code: 2, state: false },
{ hobby: '敲代码', code: 3, state: true },
{ hobby: '看书', code: 4, state: false },
{ hobby: '玩魔方', code: 5, state: true }
])
const isAll = computed({
// ◆全选影响小选
set(val) {
list.value.forEach((item) => {
item.state = val
})
},
// ◆小选影响全选
get() {
return list.value.every((item) => item.state)
}
})
// ◆反选影响小选
const revCheck = () => {
list.value.forEach((item) => {
item.state = !item.state
})
}
return { list, isAll, revCheck }
}
}
</script>
四、react 实现 全选、反选、小选
// react 实现全选、反选、小选
import React, { useState, useEffect } from 'react'
const CheckBox = () => {
const arr = [
{ id: 1, hobby: '吃饭', state: true },
{ id: 2, hobby: '睡觉', state: false },
{ id: 3, hobby: '敲代码', state: true },
{ id: 4, hobby: '玩魔方', state: false }
]
const [list, setList] = useState(arr)
// ◆ 一进入页面获取 localStorage 里面存储的数据,没有就用 arr
// 相当于 componentDidMount
useEffect(() => {
setList((arr) => {
return JSON.parse(localStorage.getItem('list')) || arr
})
}, [])
// ◆小选框是否选中的状态
const singleChangeHandler = (id, flag) => {
console.log(id, flag, '小选框')
setList((list) => {
return list.map(item => {
if (item.id === id) {
return {
...item,
state: flag
}
} else {
return item
}
})
})
}
const [flag, setFlag] = useState(false)
// ◆全选/全不选
const checkAllHandler = (isCheck) => {
// 1.先设置自己的 checked 值
setFlag(isCheck)
// 2.循环其他复选框的值和自己一样
setList((list) => {
return list.map(item => {
return {
...item,
state: isCheck
}
})
})
}
// ◆小选影响全选 (相当于 componentDidUpdate)
useEffect(() => {
// 1.只要有一个小选框没选中,全选就是 false,否则 true
setFlag(() => list.every(item => item.state))
// 2.持久化存储 localStorage
localStorage.setItem('list', JSON.stringify(list))
}, [list])
// ◆反选
const revCheckHandler = () => {
setList((list) => {
return list.map(item => {
return {
...item,
state: !item.state
}
})
})
}
return <div>
<input type="checkbox" checked={flag} onChange={() => checkAllHandler(!flag)} />全选
<input type="checkbox" onChange={() => revCheckHandler()} />反选
{list.map((item) => {
return (<div key={item.id}>
<input type="checkbox" onChange={() => singleChangeHandler(item.id, !item.state)} checked={item.state} value={item.hobby} />{item.hobby}
</div>)
})}
</div>
}
export default CheckBox