Day10 - JS 实现 Checkbox 中按住 Shift 的多选功能
Day10 - JS 实现 Checkbox 中按住 Shift 的多选功能
作者:liyuechun
简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 10 篇。完整中文版指南及视频教程在 从零到壹全栈部落。
项目效果
操作方法
- 选中 A 项
- 按下 Shift
- 再选中 B 项
- A-B 之间的所有项都被选中或者取消
实现方法
方法一
Wes Bos 在文档里提供了一种解决办法:用一个变量,来标记这个范围。
变量初始值为 false,当按下 Shift 键且同时选中了某个元素的时候,遍历所有项,遍历过程中,若遇到 A 或 B,则将标记值取反。同时,将所有标记为 true 的项设置为选中。
let startChecked;
// 处理方法一:用变量 inBetween 对需要选中的元素进行标记
function handleCheck0(e) {
let inBetween = false;
if(e.shiftKey && this.checked){
boxs.forEach(input => {
console.log(input);
if(input === startChecked || input ===this) {
inBetween = !inBetween;
}
if(inBetween) {
console.log("on");
input.checked = true;
}
});
}
startChecked = this;
}
方法二
上面会出现一个问题,初次加载页面时,按住 Shift 再点击某一项,此项之后的元素都会被选中。此外,对于取消选中,无法批量操作。下面方法三是缉熙Soyaine 的操作逻辑。方法二是我对Wes Bos实现方法逻辑的改进,方法二和方法三取消和选中均可批量操作。
let startChecked;
let onOff = false;
// 处理方法二:新增onOff变量存储复选框将要改变的状态
function handleCheck2(e) {
let inBetween = false;
if (e.shiftKey) {
onOff = startChecked.checked ? true : false;
boxs.forEach(input => {
console.log(input);
if (input === startChecked || input === this) {
inBetween = !inBetween;
}
if (inBetween && input !== startChecked || input === this) {
input.checked = onOff;
}
});
startChecked = this;
}
startChecked = this;
}
onOff = startChecked.checked ? true : false; 根据startChecked设置要改变的状态。同时在if (inBetween && input !== startChecked || input === this)代码里面做了修改,新增了|| input === this,否则会出现最后一个的状态和其他复选框状态不一致的bug。
方法三
方法一中的 inBetween 仅仅表示此项是否在被选中的范围中,此处会赋给它更多的意义,用它来表示此项是选中还是未选中,而范围划定则由数组来解决。
首先将获取到的 <input> 组转化为数组,针对每次操作,获取 A 和 B,利用 indexOf() 来获得 A 和 B 在数组中的索引值,由此即可确定范围,并能通过 slice() 来直接截取 A-B 的所有 DOM 元素,并进行状态改变的操作,而变量 onOff 表示 A-B 范围内的状态,true 表示选中,false 表示取消选中。
const boxArr = Array.from(boxs);
let startChecked;
let onOff = false;
// 处理方法二:利用数组索引获取需要选中的范围
function handleCheck1(e) {
if(!startChecked) startChecked = this;
onOff = startChecked.checked ? true : false;
if(e.shiftKey) {
let start = boxArr.indexOf(this);
let end = boxArr.indexOf(startChecked);
boxArr.slice(Math.min(start, end), Math.max(start, end) + 1)
.forEach(input => input.checked = onOff);
console.log(start + "+" + end);
}
startChecked = this;
}
转换 Nodelist 为数组
const boxs = document.querySelectorAll('.inbox input[type="checkbox"]');
const boxArr = Array.from(boxs);针对按下了 Shift 键的情况,获取 A-B 范围
let start = boxArr.indexOf(this);
let end = boxArr.indexOf(startChecked);截取该范围内的数组元素,并改变选中状态
boxArr.slice(Math.min(start, end), Math.max(start, end) + 1)
.forEach(input => input.checked = onOff);确定选中 or 取消选中
onOff = startChecked.checked ? true : false;标记 A 值
if(!startChecked) startChecked = this;
/* ... */
startChecked = this;
源码下载
社群品牌:从零到壹全栈部落
定位:寻找共好,共同学习,持续输出全栈技术社群
业界荣誉:IT界的逻辑思维
文化:输出是最好的学习方式
官方公众号:全栈部落
社群发起人:春哥(从零到壹创始人,交流微信:liyc1215)
技术交流社区:全栈部落BBS
全栈部落完整系列教程:全栈部落完整电子书学习笔记
| 关注全栈部落官方公众号,每晚十点接收系列原创技术推送 |
|---|
Day10 - JS 实现 Checkbox 中按住 Shift 的多选功能的更多相关文章
- js获取checkbox中所有选中值及input后面所跟的文本
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- D3.js v4版本 按住shift键框选节点demo
http://download.csdn.net/download/qq_25042329/10139649
- jQuery 判断多个 input checkbox 中至少有一个勾选
html ( 使用 TP 标签 ) : <volist name="health_tag" id="htag"> <input type=&q ...
- js~一个列表中包含上移下移删除等功能
最近做了一个项目,包括了一个列表页,为了用户体验,操作均使用JS实现,其中包括在列表中实现上移,下移,删除等功能,前台JS,后端数据修改使用AJAX,本文主要说一下前台JS这块 先看一下页面的截图
- [原创]纯JS实现网页中多选复选框checkbox和单选radio的美化效果
图片素材: 最终效果图: <html><title> 纯JS实现网页中多选复选框checkbox和单选radio的美化效果</title><head>& ...
- ASP.NET js控制treeview中的checkbox实现单选功能
ASP.NET js控制treeview中的checkbox实现单选功能 function OnTreeNodeChecked() { var element = window.event.srcEl ...
- 使用js获取checkbox控件在GridView中的第几行
这次的知识点是如何使用js获取checkbox控件所在的是第几行!!! 我们可以使用 JavaScript 中自带的 rowIndex 和 cellIndex 来获取行和列的键值 (从0开始) 这两个 ...
- js实现reqire中的amd,cmd功能
js实现reqire中的amd,cmd功能 ,大概实现了 路径和模块 引入等重要功能. 本帖属于原创,转载请出名出处. <!DOCTYPE html PUBLIC "-//W3C//D ...
- js获取URL中的参数
js获取URL中的一些参数的意思 location对象 含有当前URL的信息. 属性 href 整个URL字符串. protocol 含有URL第一部分的字符串,如http: host 包含有URL中 ...
随机推荐
- html续篇及初识爬虫
今日内容概要 form表单 requests模块 可以模拟浏览器朝服务端发送各式各样的请求 cookie与session requests模块小案例(网站的基本防爬措施) 今日内容详细 form表单 ...
- Django中的Session和cookie
Session和cookie 参考文献:https://www.cnblogs.com/wupeiqi/articles/5246483.html 1.问题引入 1.1 cookie是什么? 保存在客 ...
- [csi]浅聊ceph-csi组件
描述 ceph-csi扩展各种存储类型的卷的管理能力,实现第三方存储ceph的各种操作能力与k8s存储系统的结合.调用第三方存储ceph的接口或命令,从而提供ceph数据卷的创建/删除.挂载/解除 ...
- ASP.NET Core 6框架揭秘实例演示[19]:数据加解密与哈希
数据保护(Data Protection)框架旨在解决数据在传输与持久化存储过程中的一致性(Integrity)和机密性(confidentiality)问题,前者用于检验接收到的数据是否经过篡改,后 ...
- 微服务7:通信之RPC
★微服务系列 微服务1:微服务及其演进史 微服务2:微服务全景架构 微服务3:微服务拆分策略 微服务4:服务注册与发现 微服务5:服务注册与发现(实践篇) 微服务6:通信之网关 微服务7:通信之RPC ...
- pandas连接数据库
项目中使用pandas方法读取数据库数据可能用到的方法 使用pandas连接数据库 例如 mysql_conn = pymysql.connect(host='172.28.*.***', port= ...
- 25 面向对象编程 继承概念 代码 快捷键 super注意点
继承概念 继承的本质是对某一批的抽象,从而实现对现实世界更美好的建模. extends的意思的"扩展".子类是父类的扩展. JAVA中类只有单继承,没有多继承!理解:一个儿子只能有 ...
- x86-7-页式管理(Paging)
x86-7-页式管理(Paging) 页式管理是重中之重! 在段式管理下操作系统的运作出现了很多问题,因为段的长度不定,在分配内存时,可能会发生内存中的空闲区域小于要加载的段,或者空闲区域远远大于要加 ...
- 了解Redis持久化
Redis是一个键值对数据库服务器,由于Redis是内存数据库,那么有很多内存的特点,例如掉电易失,或者进程退出,服务器中的数据也将消失不见,所以需要一种方法将数据从内存中写到磁盘,这一过程称之为数据 ...
- c# winform 窗体 对话框绑定的值如何填到主窗体问题
这段代码放在主窗体中 private void txt_KeJiaAModel_DoubleClick(object sender, EventArgs e) { TimerEvent(); } // ...