1. HTML+JS实现简单的多选选项的全选反选按钮
多选菜单的全选和反选按钮十分常见,今天就实现一个简单的全选和全不选效果。
全选反选按钮关键点在于check类型input的checked属性,当该属性为true时为选中状态,为false时为不选中状态。
1.1. 代码
1.1.1. page-checkbox-select.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>代表建议</title>
<meta name="viewport"
content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT">
<script type="text/javascript" src="../static/js/init-rem.js"></script>
<link rel="stylesheet" type="text/css" href="../static/css/mui.min.css"/>
<script type="text/javascript" src="../static/js/mui.min.js"></script>
<link rel="stylesheet" type="text/css" href="../static/css/mui-icons-extra.css"/>
<link rel="stylesheet" type="text/css" href="../static/css/mui.loading.css"/>
<script type="text/javascript" src="../static/js/mui.loading.js"></script>
<script type="text/javascript" src="../static/js/my-mui-loading.js"></script>
<link rel="stylesheet" type="text/css" href="../static/css/mescroll.min.css"/>
<script type="text/javascript" src="../static/js/mescroll.min.js"></script>
<script type="text/javascript" src="../static/js/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="../static/helper/net-helper.js"></script>
<script type="text/javascript" src="../static/helper/init-helper.js"></script>
<link rel="stylesheet" type="text/css" href="../static/css/base.css"/>
<link rel="stylesheet" type="text/css" href="../css/page-checkbox-select.css"/>
<script type="text/javascript" src="../static/js/vconsole.min.js"></script>
<script type="text/javascript">
// var vc = new VConsole()
</script>
</head>
<body>
<!--标题区域-->
<div class="base-title-bar">
<span class="base-title-back" onclick="history.go(-1)">
<img src="../img/icon/icon_back.png"/>
</span>
<h1>代表建议</h1>
<span class="base-title-back"></span>
</div>
<!--内容区域-->
<div class="base-mescroll-white">
<!--搜索-->
<div class="query-layout">
<div class="query-input">
<span class="query-img">
<img src="../img/icon/icon-query-gray.png"/>
</span>
<input class="base-ellipsis" type="text"
id="name" name="name"
placeholder="请输入搜索内容" value=""/>
</div>
<span class="query-title">搜索</span>
</div>
<!--搜索数量-->
<div class="base-header">
<span class="icon"></span>
<span class="text base-ellipsis">
共搜索出<em id="total_num">0</em>条数据
</span>
</div>
<div class="check-layout" onclick="checkClick()">
<span class="check-img">
<img id="check_img_id" src="../img/icon/icon_select_no.png"/>
</span>
<span id="check_txt_id" class="check-txt">全选</span>
</div>
<!--列表-->
<div class="mescroll base-mescroll5">
<ul id="list_id" class="list-layout"></ul>
</div>
</div>
<script type="text/javascript" src="../js/page-checkbox-select.js"></script>
</body>
</html>
1.1.2. page-checkbox-select.css
/*搜索布局*/
.query-layout {
display: flex;
display: -webkit-flex;
flex-direction: row;
align-items: center;
-webkit-align-items: center;
padding: 0.25rem 0.2rem 0.2rem 0.2rem;
background-color: white;
}
.query-input {
display: flex;
display: -webkit-flex;
flex-direction: row;
align-items: center;
-webkit-align-items: center;
height: 0.7rem;
line-height: 0.7rem;
flex: 1;
opacity: 1;
background-color: #f5f5f5;
border-radius: 0.5rem;
border: 0.01rem solid #999999;
}
.query-input > input {
flex: 1;
font-size: 0.30rem;
margin: 0;
padding: 0 0 0 0.1rem;
color: #333333;
opacity: 1;
height: 0.6rem;
line-height: 0.6rem;
background-color: #f5f5f5;
border-radius: 0.5rem;
border: 0.01rem solid #f5f5f5;
}
.query-img {
overflow: hidden;
width: 0.7rem;
height: 0.7rem;
display: flex;
border-radius: 0.5rem;
justify-content: center;
align-items: center;
margin: 0 0 0 0;
}
.query-img img {
height: 60%;
}
.query-title {
font-size: 0.30rem;
color: dodgerblue;
margin-left: 0.2rem;
}
/*列表布局*/
.list-layout {
overflow-x: hidden;
}
.list-layout li {
overflow-x: hidden;
background: #fff;
margin: 0.2rem 0.2rem;
padding: 0.2rem 0.1rem;
border: 0.02rem solid #efeff4;
border-radius: 0.1rem;
box-shadow: 0.03rem 0.03rem 0.03rem 0.03rem #efeff4;
}
.list-item {
overflow: hidden;
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
}
.list-item-img {
overflow: hidden;
width: 1.5rem;
height: 1.0rem;
display: flex;
justify-content: center;
align-items: center;
margin: 0 0.2rem 0 0.1rem;
}
.list-item-title {
color: #000;
font-size: 0.32rem;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
-webkit-box-align: center;
-webkit-line-clamp: 1;
line-height: 0.5rem;
}
.list-item-content {
color: #333;
font-size: 0.30rem;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
-webkit-box-align: center;
-webkit-line-clamp: 1;
}
.list-item-content-bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.list-item-time-label {
display: inline-block;
color: #999999;
font-size: 0.26rem;
}
.list-item-status-layout {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.list-item-status-label {
color: #999999;
font-size: 0.26rem;
margin-right: 0.1rem;
}
.list-item-status-value {
color: #007AFF;
font-size: 0.26rem;
}
.li-layout {
overflow: hidden;
display: flex;
flex-direction: row;
width: 100%;
align-items: center;
padding: 0.1rem 0.2rem;
}
.item-checkbox {
width:0.4rem;
height:0.4rem;
}
.li-item-layout {
display: flex;
flex-direction: column;
justify-content: space-between;
margin-left: 0.3rem;
margin-right: 0.2rem;
}
.check-layout{
display: flex;
flex-direction: row;
align-items: center;
}
.check-img {
overflow: hidden;
width: 0.9rem;
height: 0.7rem;
display: flex;
border-radius: 0.5rem;
justify-content: center;
align-items: center;
margin: 0 0 0 0;
}
.check-img img {
height: 80%;
}
.check-txt{
color: #333;
font-size: 0.34rem;
}
1.1.3. page-checkbox-select.js
var pageType = getParamByKey('pageType');
var dataModel = {
isSelectAll: false,
totalSize: 0//总条数
};
$(function () {
//返回上一页面
backPage()
//初始化数据
initData();
});
/**
* 初始化数据
*/
function initData() {
//联网加载数据
getListData(1, 10,
function (curPageData) {
//设置列表数据
setListData(curPageData);
}, function () {
});
}
/**
* 设置列表数据
* @param {Object} curPageData
*/
function setListData(listData) {
var listDom = document
.getElementById("list_id");
listData.forEach(function (item, index) {
var htmlStr =
` <div class="li-layout"
onclick="goDetail2(this)"
data-title=" ${item.suggestionTitle || ''}">
<input class="item-checkbox" type="checkbox"
value="${item.suggestionTitle || ''}" >
<label class="li-item-layout">
<div class="list-item-title">
${item.suggestionTitle || ''}
</div>
<div class="list-item-content">
${item.content || ''}
</div>
</label>
</input>
</div>`
var liDom = document.createElement("li");
liDom.innerHTML = htmlStr;
liDom.setAttribute('data-id', item.id);
listDom.appendChild(liDom); //加在列表的后面,上拉加载
})
}
/**
* 加载列表数据
*/
function getListData(pageNum, pageSize,
successCallback, errorCallback) {
$.getJSON(`../json/checkboxInfo.json`,
function (result) {
var newArr = [];
if (result && isNotNull(result.rows)) {
$('#total_num').html(result.total);
dataModel.totalSize = result.total;
if (result) {
newArr = newArr.concat(result.rows);
successCallback && successCallback(newArr);
}
} else {
successCallback && successCallback(newArr);
}
});
}
function htmlForResult(webParms) {
console.log("adfewf====", webParms)
}
/**
* 单击进详情
*/
function goDetail2(obj) {
var title = $(obj).attr('data-title');
mui.toast(title)
}
/**
* 设置全选、全不选
*/
function checkClick() {
var src = ''
var txt = ''
if (dataModel.isSelectAll) {
src = '../img/icon/icon_select_no.png'
txt = '全不选'
} else {
src = '../img/icon/icon_select.png'
txt = '全选'
}
dataModel.isSelectAll = !dataModel.isSelectAll
$('#check_img_id').attr('src', src);
$('#check_txt_id').html(txt);
var itemCheckbox = document
.getElementsByClassName("item-checkbox");
for (var i = 0; i < itemCheckbox.length; i++) {
var h = itemCheckbox[i];
h.checked = dataModel.isSelectAll;
}
}
1.1.4. checkboxInfo.json
{
"total": 20,
"rows": [
{
"createBy": "1",
"createTime": "2024-03-25 21:48:24",
"updateBy": "1",
"updateTime": "2024-03-25 21:48:24",
"remark": null,
"id": "cb6d917f-39ef-4d36-9904-b6f344e405dc",
"suggestionTitle": "0325测试",
"content": "测试",
"initalRepresentative": "测试",
"handleTime": null,
"status": "2",
"unitAndPostion": "测试",
"mobile": "",
"contactStation": "1",
"imgName": "社区服务.jpg",
"imgPath": "/lingbao/社区服务_1711374500511.jpg",
"fileName": "testDoc.docx",
"filePath": "/lingbao/testDoc_1711374503149.docx",
"delFlag": null,
"targetDept": "100",
"targetDeptName": "灵宝市人大机关",
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": null,
"evaluateContent": null,
"handleOption": null,
"pageName": null
},
{
"createBy": "1",
"createTime": "2024-03-19 15:07:04",
"updateBy": "1",
"updateTime": "2024-03-19 15:07:04",
"remark": null,
"id": "b9f6e77f-7046-413b-b747-549c0feed472",
"suggestionTitle": "阿斯顿",
"content": "阿斯顿",
"initalRepresentative": "221",
"handleTime": null,
"status": "2",
"unitAndPostion": "阿斯顿",
"mobile": "11",
"contactStation": "2",
"imgName": "renxiang.jpeg",
"imgPath": "/npclb/renxiang_1710832016573.jpeg",
"fileName": "地震预案.pdf",
"filePath": "/npclb/地震预案_1710832021934.pdf",
"delFlag": null,
"targetDept": "201",
"targetDeptName": "教科文委",
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": null,
"evaluateContent": null,
"handleOption": null,
"pageName": null
},
{
"createBy": "1",
"createTime": "2024-03-19 11:59:51",
"updateBy": "1",
"updateTime": "2024-03-19 11:59:51",
"remark": null,
"id": "700c8dfd-67fc-4c92-a1db-0eb123806f27",
"suggestionTitle": "测试1159",
"content": "测试1159测试1159",
"initalRepresentative": "测试1159",
"handleTime": null,
"status": "2",
"unitAndPostion": "测试1159",
"mobile": "18888999098",
"contactStation": "1",
"imgName": null,
"imgPath": null,
"fileName": null,
"filePath": null,
"delFlag": null,
"targetDept": "205",
"targetDeptName": "选工委",
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": null,
"evaluateContent": null,
"handleOption": null,
"pageName": null
},
{
"createBy": "1",
"createTime": "2024-03-19 10:41:48",
"updateBy": "1",
"updateTime": "2024-03-19 10:41:48",
"remark": null,
"id": "bc96741f-efb7-4a1c-9d0e-60d89dea13a9",
"suggestionTitle": "0319测试",
"content": "111",
"initalRepresentative": "11",
"handleTime": null,
"status": "2",
"unitAndPostion": "11",
"mobile": "111",
"contactStation": "2",
"imgName": null,
"imgPath": null,
"fileName": null,
"filePath": null,
"delFlag": null,
"targetDept": "201",
"targetDeptName": "教科文委",
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": null,
"evaluateContent": null,
"handleOption": null,
"pageName": null
},
{
"createBy": "1",
"createTime": "2024-03-19 10:41:24",
"updateBy": "1",
"updateTime": "2024-03-19 10:41:24",
"remark": null,
"id": "01185ab4-ace4-454c-9d54-d237a2969907",
"suggestionTitle": "镇建议测试",
"content": "建议测试建议测试建议测试",
"initalRepresentative": "Bcc",
"handleTime": null,
"status": "2",
"unitAndPostion": "SSSe",
"mobile": "19999888776",
"contactStation": "1",
"imgName": null,
"imgPath": null,
"fileName": null,
"filePath": null,
"delFlag": null,
"targetDept": "201",
"targetDeptName": "教科文委",
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": null,
"evaluateContent": null,
"handleOption": null,
"pageName": null
},
{
"createBy": "1",
"createTime": "2024-03-19 10:39:34",
"updateBy": "1",
"updateTime": "2024-03-19 10:39:34",
"remark": null,
"id": "e49e8a71-b198-427e-b247-5be145526a3f",
"suggestionTitle": "市建议测试",
"content": "建议测试建议测试建议测试",
"initalRepresentative": "Acc",
"handleTime": null,
"status": "2",
"unitAndPostion": "sss",
"mobile": "19999999777",
"contactStation": "1",
"imgName": null,
"imgPath": null,
"fileName": null,
"filePath": null,
"delFlag": null,
"targetDept": "208",
"targetDeptName": "城环委",
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": null,
"evaluateContent": null,
"handleOption": null,
"pageName": null
},
{
"createBy": "1",
"createTime": "2024-03-04 15:58:57",
"updateBy": "123",
"updateTime": "2024-03-04 16:06:25",
"remark": null,
"id": "53cd8caa-80b8-4073-abd1-aee45ce26369",
"suggestionTitle": "11",
"content": "22",
"initalRepresentative": "33",
"handleTime": null,
"status": "3",
"unitAndPostion": "44",
"mobile": "18888888888",
"contactStation": "1",
"imgName": null,
"imgPath": null,
"fileName": null,
"filePath": null,
"delFlag": null,
"targetDept": "201",
"targetDeptName": "教科文委",
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": "12345",
"evaluate": null,
"evaluateContent": null,
"handleOption": null,
"pageName": null
},
{
"createBy": "2",
"createTime": "2024-01-11 14:37:07",
"updateBy": "2",
"updateTime": "2024-01-11 14:37:19",
"remark": null,
"id": "6bd2c1e2-911d-461c-a1ac-1971ae5dfe0e",
"suggestionTitle": "测1102",
"content": "2344",
"initalRepresentative": "231",
"handleTime": null,
"status": "4",
"unitAndPostion": "32421",
"mobile": "2343214",
"contactStation": "1",
"imgName": "icon_affix_1704955019472.png",
"imgPath": "/xin-wu-grid/icon_affix_1704955019472.png",
"fileName": "icon_base_house_add_1704955022206.png",
"filePath": "/xin-wu-grid/icon_base_house_add_1704955022206.png",
"delFlag": null,
"targetDept": null,
"targetDeptName": null,
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": "2",
"evaluateContent": "3243544325",
"handleOption": null,
"pageName": null
},
{
"createBy": "2",
"createTime": "2024-01-11 10:28:16",
"updateBy": "2",
"updateTime": "2024-01-11 11:32:52",
"remark": null,
"id": "7184c1ad-396f-4b5c-a259-3aedbd52b92d",
"suggestionTitle": "建议标题1101",
"content": "建议内容",
"initalRepresentative": "发起建议代表",
"handleTime": null,
"status": "3",
"unitAndPostion": "工作单位及职务额",
"mobile": "1787878787",
"contactStation": "1",
"imgName": "icon_add_1704940073320.png,icon_app_1704940075958.png",
"imgPath": "/xin-wu-grid/icon_add_1704940073320.png,/xin-wu-grid/icon_app_1704940075958.png",
"fileName": "icon_apply_activity_theme_1704940080387.png,267b12b7e91910c246249c78f70fe5f2_1704940089274.mp4",
"filePath": "/xin-wu-grid/icon_apply_activity_theme_1704940080387.png,/xin-wu-grid/267b12b7e91910c246249c78f70fe5f2_1704940089274.mp4",
"delFlag": null,
"targetDept": null,
"targetDeptName": "人事科",
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": "1",
"evaluateContent": "4325",
"handleOption": null,
"pageName": null
},
{
"createBy": "2",
"createTime": "2024-01-11 10:21:47",
"updateBy": "2",
"updateTime": "2024-01-11 10:21:47",
"remark": null,
"id": "c4cf9c24-3f10-40ff-a461-25108021d751",
"suggestionTitle": "建议标题101801",
"content": "内容",
"initalRepresentative": "发起建议代表",
"handleTime": null,
"status": null,
"unitAndPostion": "工作单位及职务",
"mobile": "17676767676",
"contactStation": "2",
"imgName": "",
"imgPath": "",
"fileName": "",
"filePath": "",
"delFlag": null,
"targetDept": null,
"targetDeptName": null,
"handleUnit": null,
"handleUnitName": null,
"handleId": null,
"handleSuggestion": null,
"evaluate": null,
"evaluateContent": null,
"handleOption": null,
"pageName": null
}
],
"code": 200,
"msg": "查询成功"
}
1.2. 方案
1.2.1. html]如何扩大checkbox点击区域
用 label 包裹,扩大 label 尺寸
<input class="item-checkbox" type="checkbox"
value="${item.suggestionTitle || ''}" >
<label class="li-item-layout">
<div class="list-item-title">
${item.suggestionTitle || ''}
</div>
<div class="list-item-content">
${item.content || ''}
</div>
</label>
</input>
(1)方法一:将input和label放在同一个标签p中同时lable的for属性的值等于input的id属性值就可以实现点击label同时控制input 。
<input type="checkbox" id="c2">
<label for="c2">内容2</label>
(2)方法二:abel联动checkbox时,若label包含在checkbox外层时label不需for属性,设置label的display属性为block时可以使整个div联动。
<label>
<input type="checkbox">
<span>内容1</span>
</label>
1.2.2. 扩大checkbox的点击区域
具体是为了在表格中点击 td 也能选中,做法是为 td 元素添加点击事件,在点击事件里面触发checkbox的点击事件:
<td onclick="clickTd($(this))"><input type="checkbox" name="task" onclick="oncheckAll(event)"></td>
function clickTd($t){
$t.children("input").click();
}
当这样的问题是点击checkbox的时候,因为页面元素所在区域重叠,点击事件向上传递,会首先触发checkbox的点击事件,然后触发 td 的点击事件,然后 td 的点击事件会被再次触发,就相当于checkbox点击了两次,所以需要 checkbox 的点击事件执行完之后,让该点击事件停止传递。
checkbox的点击事件里面加入拦截即可:
function oncheckAll(event){
event.stopPropagation();
}