模拟系统内置下拉框,使得在所有的系统以及浏览器中具有同样的表现,目标是功能分解,利用 mixin 分离实现。
下拉框功能点分析:
1.可以存储值,是一个存储数据的容器,相当于 readonly 的 input。
2.有下拉箭头,点击下拉箭头可以弹出选项列表。(实际上点击存储容器也有同样的表现)。
3.选项列表本质是一个 overlay,选项列表弹出后会遮盖存储容器下面的内容。
4.选项列表浮层具有默认的对齐属性,即选项列表的左上角与存储容器的左下角对齐。
5.最重要的:下拉框的内容(选项列表)是一个列表,可以通过鼠标或键盘选中特定列表项值。
下拉框实现设计:
1.值容器
值容器使用 input 来表现,不过新增自定义属性 data-value 用来表示下拉框的值,input 本身的 value 则用来表示下拉框值的对应展现内容。
值容器作为最基本的实现,具备 inputNode(关联input) ,inputValue (下拉框值),inputDisplay(下拉框展现内容)三个属性,不仅能为下拉框提供支持,经过扩展也可以作为自动补全组件的存储底层:
function Base(){} Base.ATTRS = { inputNode:{ setter:function(el) { return Node.one(el); } }, inputValue:{ }, inputDisplay:{ valueFn:function() { this.get("inputNode").val(); } } };
2.列表
列表表示列表数据项的有序组合,列表使用语义化的 ul ,li来表示:
var LIST_WRAP_TMPL = "<ul class='{listClass}'>"; var LIST_ITEM_TMPL = "<li class='{listItemClass}' data-value='{listItemValue}'>{listItem}</li>";
具备 listData (列表内容数据),hoverListItem(当前鼠标掠过的单个表项),selectListItem(当前鼠标点击确定的单个表项),以及一些样式类配置:
function List(){} List.ATTRS = { listData:{ setter:function(v) { return v || []; } }, listClass:{ value:"ks-selectable2-list" }, listItemClass:{ value:"ks-selectable2-list-item" }, listItemHoverClass:{ value:"ks-selectable2-list-item-hover" }, listItemActiveClass:{ value:"ks-selectable2-list-item-active" }, hoverListItem:{setter:smooth}, activeListItem:{setter:smooth}, selectListItem:{setter:smooth} };
主要逻辑为监控鼠标动作来更新对应属性值(hover,click)。(经扩展也可支持键盘)。
3.overlay 特性扩充
通过扩充 overlay 的特性(盒子,定位,对齐)并结合上述 1,2 的 input 和 list 来产生模拟系统的下拉框类
UIBase.create([ S.require("uibase/box"), S.require("uibase/contentbox"), S.require("uibase/position"), UA['ie'] == 6 ? S.require("uibase/shim") : null, S.require("uibase/align"), SelectBase, SelectList);
下拉框要处理自己的逻辑了:
1.监控 list 的选择项变化,同步 input 的展现内容与自定义的 data-value 属性值。
2.将 input 设为只读,并且屏蔽 input 获得焦点 (系统下拉框的 input 是不会出现光标的)。
3.添加下拉箭头。
3.控制列表显示:点击 input 以及下拉箭头进行列表的显示和隐藏,点击空白区域隐藏列表。
4.设置默认对齐属性,列表默认对齐于 input。
3.demo