Day10 - JS 实现 Checkbox 中按住 Shift 的多选功能

作者:liyuechun
简介:JavaScript30Wes Bos 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 10 篇。完整中文版指南及视频教程在 从零到壹全栈部落

项目效果

操作方法

  1. 选中 A 项
  2. 按下 Shift
  3. 再选中 B 项
  4. 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;
}
  1. 转换 Nodelist 为数组

    const boxs = document.querySelectorAll('.inbox input[type="checkbox"]');
    const boxArr = Array.from(boxs);
  2. 针对按下了 Shift 键的情况,获取 A-B 范围

    let start = boxArr.indexOf(this);
    let end = boxArr.indexOf(startChecked);
  3. 截取该范围内的数组元素,并改变选中状态

    boxArr.slice(Math.min(start, end), Math.max(start, end) + 1)
    .forEach(input => input.checked = onOff);
  4. 确定选中 or 取消选中

    onOff = startChecked.checked ? true : false;
  5. 标记 A 值

    if(!startChecked) startChecked = this;
    /* ... */
    startChecked = this;

源码下载

Github Source Code

社群品牌:从零到壹全栈部落

定位:寻找共好,共同学习,持续输出全栈技术社群

业界荣誉:IT界的逻辑思维

文化:输出是最好的学习方式

官方公众号:全栈部落

社群发起人:春哥(从零到壹创始人,交流微信:liyc1215)

技术交流社区:全栈部落BBS

全栈部落完整系列教程:全栈部落完整电子书学习笔记

关注全栈部落官方公众号,每晚十点接收系列原创技术推送

Day10 - JS 实现 Checkbox 中按住 Shift 的多选功能的更多相关文章

  1. js获取checkbox中所有选中值及input后面所跟的文本

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  2. D3.js v4版本 按住shift键框选节点demo

    http://download.csdn.net/download/qq_25042329/10139649

  3. jQuery 判断多个 input checkbox 中至少有一个勾选

    html ( 使用 TP 标签 ) : <volist name="health_tag" id="htag"> <input type=&q ...

  4. js~一个列表中包含上移下移删除等功能

    最近做了一个项目,包括了一个列表页,为了用户体验,操作均使用JS实现,其中包括在列表中实现上移,下移,删除等功能,前台JS,后端数据修改使用AJAX,本文主要说一下前台JS这块 先看一下页面的截图

  5. [原创]纯JS实现网页中多选复选框checkbox和单选radio的美化效果

    图片素材: 最终效果图: <html><title> 纯JS实现网页中多选复选框checkbox和单选radio的美化效果</title><head>& ...

  6. ASP.NET js控制treeview中的checkbox实现单选功能

    ASP.NET js控制treeview中的checkbox实现单选功能 function OnTreeNodeChecked() { var element = window.event.srcEl ...

  7. 使用js获取checkbox控件在GridView中的第几行

    这次的知识点是如何使用js获取checkbox控件所在的是第几行!!! 我们可以使用 JavaScript 中自带的 rowIndex 和 cellIndex 来获取行和列的键值 (从0开始) 这两个 ...

  8. js实现reqire中的amd,cmd功能

    js实现reqire中的amd,cmd功能 ,大概实现了 路径和模块 引入等重要功能. 本帖属于原创,转载请出名出处. <!DOCTYPE html PUBLIC "-//W3C//D ...

  9. js获取URL中的参数

    js获取URL中的一些参数的意思 location对象 含有当前URL的信息. 属性 href 整个URL字符串. protocol 含有URL第一部分的字符串,如http: host 包含有URL中 ...

随机推荐

  1. QT之HTTP

    概述 QT的HTTP操作都是异步的,内部通过线程实现. 相关类: QNetworkAccessManager [发送网络请求并接收响应] QNetworkReply [服务响应] QNetworkRe ...

  2. Python第二

    今日内容概要 基本运算符 流程控制 字符编码 理论特别多.结论特别少 文件处理 今日内容详细 基本运算符 1.算数运算符 x = 1 y = 5 res = x + y #加 res1 = x - y ...

  3. MySQL — DCL语言

    全称 Data Control Language.数据控制语言,用来创建数据库用户.控制数据库的访问权限. 1.用户管理 1.1.查询用户 select * from user; 1.2.创建用户 - ...

  4. Tableau学习step1一Tableau概述

    本文首发于博客冰山一树Sankey,去博客浏览效果更好. 一.Tableau优缺点 优点 ·简单易用,只要是会用 EXCEL,几分钟就可掌握 Tableau的基本用法 急速高效 ·结果美观 ·轻松整合 ...

  5. mplus数据分析:增长模型潜增长模型与增长混合模型再解释

    混合模型,增长混合模型这些问题咨询的同学还是比较多的,今天再次尝试写写它们的区别,希望对大家进一步理解两种做轨迹的方法有帮助. 首先,无论是LCGA还是GMM,它们都是潜增长模型的框框里面的东西: L ...

  6. golang 中 channel 的详细使用、使用注意事项及死锁分析

    目录 1.什么是 channel,介绍管道 2.channel 的基本使用 3.channel 的使用场景 4.使用 channel的注意事项及死锁分析 什么是 channel 管道 它是一个数据管道 ...

  7. 前端—我的第一篇博客 梦开始的地方(面向对象版tab栏)

    这是我的第一篇博客 博客生涯才开始 但是人生已经过去了二十个年头了 才开始弄这个 也没搞得太懂 我原本的想法是想搞个源代码上来 但是看了半天好像就只能传html源代码 那我还有css js的部分呢 我 ...

  8. Net6 Configuration & Options 源码分析 Part2 Options

    Net6 Configuration & Options 源码分析 Part2 Options 第二部分主要记录Options 模型 OptionsConfigurationServiceCo ...

  9. 构建 Go 应用 docker 镜像的十八种姿势

    修炼背景 我夜以继日,加班加点开发了一个最简单的 Go Hello world 应用,虽然只是跑了打印一下就退出了,但是老板也要求我上线这个我能写出的唯一应用. 项目结构如下: . ├── go.mo ...

  10. MyEclipse 05_连接mysql数据库进行增删改查

    例子: 1.在数据库中建立如下表 2. 在MyEclipse里按本主博客文MyEclipse 03_jdbc连接数据库,注意数据库名要一致  运行后在Navicat里如下: 代码如下: package ...