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

简介: Day10 - JS 实现 Checkbox 中按住 Shift 的多选功能 作者:©liyuechun简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。

作者:©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 的项设置为选中。


const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');

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;
}

checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck));

方法二

上面会出现一个问题,初次加载页面时,按住 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

春哥简介

简介: 资深讲师,全栈工程师;区块链、高可用架构技术爱好者。
个人博客:http://liyuechun.org
新浪微博:黎跃春-追时间的人
github:http://github.com/liyuechun

技术交流

  • 区块链技术交流QQ群:348924182
  • 「区块链部落」官方公众号

目录
相关文章
|
30天前
|
JavaScript 前端开发 开发者
Chrom devtools JS调试、性能优化与必备功能
Chrom devtools JS调试、性能优化与必备功能
|
28天前
|
JavaScript 安全 前端开发
js实现复制功能
js实现复制功能
13 1
|
20天前
|
开发者 Android开发 iOS开发
Xamarin开发者的神器!揭秘你绝不能错过的插件和工具,让你的开发效率飞跃式提升
【8月更文挑战第31天】Xamarin.Forms 是一个强大的框架,让开发者通过单一共享代码库构建跨平台移动应用,支持 iOS、Android 和 Windows。使用 C# 和 XAML,它简化了多平台开发流程,保持一致的用户体验。本指南通过创建一个简单的 “HelloXamarin” 应用介绍 Xamarin.Forms 的基本功能和工作原理。首先配置 Visual Studio 开发环境,然后创建并运行一个包含标题、按钮和消息标签的示例应用,展示如何定义界面布局及处理按钮点击事件。这帮助开发者快速入门 Xamarin.Forms,提高跨平台应用开发效率。
30 0
|
21天前
|
JavaScript 前端开发 开发者
Vue.js的未来已来:掌握最新功能,驾驭前端开发的新浪潮!
【8月更文挑战第30天】Vue.js作为前端开发领域的明星框架,凭借其轻量级、响应式及组件化特性,深受全球开发者喜爱。它持续进化,引入新功能并优化性能,如提升渲染速度和减小打包体积,增强TypeScript支持,简化组件编写流程,进一步提升应用响应性和加载速度,改善开发者体验。活跃的社区和丰富的开源项目如“vuejs-challenges”推动其不断发展。未来,Vue.js将探索更多新特性,如宏和非虚拟DOM模式,巩固其在现代前端框架中的领先地位。
34 0
|
23天前
|
JavaScript 前端开发
Next js:点击登录显示登录表单,点击注册显示注册表单的功能
本文提供了一个Next.js中使用React状态管理实现点击按钮切换显示登录和注册表单的功能示例,包括创建`authform.tsx`组件和在页面组件中引入使用的方法。
|
28天前
|
JavaScript 索引
js倒计时功能
js倒计时功能
28 0
|
28天前
|
JavaScript
js替换敏感词功能
js替换敏感词功能
11 0
|
28天前
|
JavaScript
js团队筛选功能
js团队筛选功能
11 0
|
28天前
|
JavaScript
js轮播图功能
js轮播图功能
12 0
|
1月前
|
JSON JavaScript 前端开发
JS三级联动功能制作
JS三级联动功能制作
24 0