JS 控件 选中

简介

我们在实现控件:列表、菜单、表格、日期选择等控件时,都需要实现选中效果,常见的选中行为有

  1. 选中一条记录,清除其他选中(单选)
  2. 选中一条记录不影响其他记录选中(多选)

 

分析

当我们去分析这些控件的实现代码时,发现选中的逻辑是几乎完全一样的,那么我们能不能把他们提取出来,这里也有2中方式:

  1. 继承:提供公用的基类,所有这些控件继承有选中功能的基类
  2. 扩展:实现一个扩展类,所有需要实现选中效果的类可以去引入这个扩展

扩展和继承的差异在前面的博客里有论述,感兴趣的可以去查看。通过对比我们可以找到使用扩展的很多好处

  1. 耦合小,在一个控件的实现过程中不考虑选中,仅在扩展中实现。
  2. 使用灵活,当一个控件的父类不需要有选中效果是,可以在子类上引入选中的扩展。
  3. 易于理解,这是一种Has A 的关系,就是说选中是控件的一个特性。

选中和取消选中

我们先来分析一下我们实现选中功能需要那些属性(Attr)、方法(method)和事件(event)。

 

  1. 点击(或者其他方式)控件的选项,其他方式包括:键盘事件、鼠标悬浮等等。
  2. 如果当前选项已经选中,那么判断控件是否多选模式
  3. 如果控件处于多选模式,那么清除控件的选中状态
  4. 触发清除选中事件
  5. 如果当前选项未选中,判断控件是否多选模式
  6. 如果当前选项处于单选状态,清除控件以及选中的选项的状态
  7. 触发选中操作

从上面选中操作的过程,我们看以看到控件需要以下属性:

selected: 选中状态

selectEvent : 选中的事件(点击、键盘事件或者鼠标悬浮)

multipleSelect: 是否允许多选,决定了选中模式是单选还是多选

触发的事件:

selected: 选项选中事件

unselected:清除选中事件

selectedchange : 选中选项发生改变的事件

这3个事件在什么时候触发我们在下面更为详细的分析,我们从上面的过程中可以抽取出需要定义的方法:

setSelected() : 设置选中

getSelected() : 获取选中的第一项

setSelection() : 多选模式下,可以设置多个选项同时被选中

getSelection(): 获取选中的所有项

clearSelection(): 清除所有选中

事件分析

如果你仔细看过上面的图,会发现,单选和多选模式下选中(selected)、清除选中(unselected)和选中改变(selectedchange)事件的触发机制有很大的差别:

  1. 单选状态下,选中一项时,需要清理之前选中的项,被清理选中的项不触发unselected事件,也不触发selectedchange事件。
  2. 多选状态下,选中和清理选中状态时都会触发对应的事件,同时触发selectedchange事件。

我们为什么这样设计?

  1. 如果单选模式下清理选中状态时也触发unselected事件会如何?
  2. 也触发selectedchange事件会如何?

如果这样,当我们选中一项时,会

  1. 触发之前选中项的unselected事件
  2. 触发之前选中项的selectedchange事件
  3. 触发当前项的selected事件
  4. 触发当前项的selectedchange事件

我们在这时候监听 selectedchange 会触发2次,如果保证逻辑正确,必须判断当前项是要选中还是要清除选中,由此带来理解和实现上的复杂性。而在多选状态下:

  1. 选中一项触发该项的 selected事件,触发该项的unselected事件
  2. 清除选中一项时触发该项的unselected事件,触发该项的selectedchange事件

所以我们可以把单选操作简单化,单选模式下选中一项那么:

  1. 触发该项的selected事件,
  2. 触发该项的selectedchange事件

实现

代码实现

菜单中的选中

选择框中的单选

选择框的多选

表格的单选

表格的多选

原文地址:https://www.cnblogs.com/zaohe/p/3002792.html