安装与调用
引入CSS:
<link rel="stylesheet" href="https://unpkg.com/lu2/theme/edge/css/common/ui/Select.css">
引入JS:
<script type="module" src="https://unpkg.com/lu2/theme/edge/js/common/ui/Select.js"></script>
本组件为Web Components,引用时需添加type="module"
,也可采用如下方式进行引用
<script type="module"> import "https://unpkg.com/lu2/theme/edge/js/common/ui/Select.js"; </script>
本组件为内置自定义元素组件,如果需要兼容Safari浏览器,还需要引入下面的JS。
<script src="https://unpkg.com/lu2/theme/edge/js/common/safari-polyfill.js"></script>
如果是npm安装调用,则:
import 'lu2/theme/edge/css/common/ui/Select.css'; import 'lu2/theme/edge/js/common/safari-polyfill.js'; import 'lu2/theme/edge/js/common/ui/Select.js';
如果 JS import语法报错,试试在业务代码中动态引入。
import('lu2/theme/edge/js/common/safari-polyfill.js'); import('lu2/theme/edge/js/common/ui/Select.js');
基本使用示意
仅需给 select 选择框添加 is="ui-select" 即可;无添加则依然表现为原生 select。
下拉框-单选
空数据
<select is="ui-select"></select>
赋值
测试禁用态样式,以及动态赋值与样式同步变化。
<select is="ui-select"> <option value="1" disabled>选项1</option> <option value="2">选项2</option> <option value="3">选项3</option> <option value="4" selected>选项4</option> <option value="5">选项5</option> <option value="6">选项6</option> </select>
// 直接value赋值 // 样式会自动同步 button.addEventListener('click', function () { select.value = select[1].value; }); // 或者 button.addEventListener('click', function () { select[1].selected = true; }); // 或者 button.addEventListener('click', function () { select[1].setAttribute('selected', true); });
和浏览器原生行为一样,value赋值不会触发change事件。
剪裁、滚动与定位
测试祖先容器存在 overflow:hidden
声明,会不会剪裁下拉列表(支持popover属性的浏览器不会剪裁):
局部滚动定位问题演示
请展开下拉,然后水平或垂直滚动试试:
可以看到下拉列表和点击按钮分离了。
局部滚动跟随实现
两种方法。
其一,使用CSS锚点定位,可以设置data-anchor="true"
或者设置is-anchor
属性。代码和效果示意如下:
<select data-anchor="true" is="ui-select"> <select is-anchor is="ui-select">
其二,采用CSS定位,让下拉内容在局部滚动容器内部,可以设置data-css-position="true"
或者设置is-css-position
属性,例如:
<select data-css-position="true" is="ui-select"> <select is-css-position is="ui-select">
注意,如果CSS定位和锚点定位同时设置,以CSS定位为准。
分组
支持 <optgroup>
元素分组。
<select is="ui-select"> <optgroup label="分组1"> <option>选项 1.1</option> </optgroup> <optgroup label="分组2"> <option>选项 2.1</option> <option>选项 2.2</option> </optgroup> <optgroup label="分组3" disabled> <option>选项 3.1</option> <option>选项 3.2</option> <option>选项 3.3</option> </optgroup> </select>
如果没有 <optgroup>
元素设置 label
描述,则分组使用分隔线分割。
<select is="ui-select"> <optgroup> <option>选项 1.1</option> </optgroup> <optgroup> <option>选项 2.1</option> <option disabled>选项 2.2</option> </optgroup> <optgroup> <option>选项 3.1</option> <option>选项 3.2</option> <option>选项 3.3</option> </optgroup> </select>
隐藏
button.addEventListener('click', function () { select.setAttribute('hidden', ''); });
滚动条
主要测试记住上一次滚动条位置的细节。
width 属性宽度外部自适应
本组件给 <select>
元素扩展了 width
属性,可以用来设置下拉框的尺寸,支持百分比值,例如:
<select is="ui-select" width="100%"> <option>选项1</option> <option>选项2</option> </select>
效果如下所示:
也支持其他类型的宽度值,例如:
<select is="ui-select" width="200"></select>
<select is="ui-select" width="8rem"></select>
使用 width
属性进行尺寸设置虽然方便,但是如果JS是后加载的,同时网速较慢,则视觉上可以感知到尺寸的变化过程,体验不好。
此时可以提前预设好相关的CSS样式,例如希望 <select>
宽度 50%,可以自行在 CSS 中设置如下所示代码(100% 宽度 Select.css 已经内置)。
select[width="50%"] { width: 50%; }
当然,也可以直接使用 style
属性进行设置,例如:
<select is="ui-select" style="width: 50%">
下拉框-复选
请选择:
选中的结果是:选项2, 选项3
<select is="ui-select" multiple> <option>选项1</option> <option selected>选项2</option> <option selected>选项3</option> <option>选项4</option> <option disabled>选项5</option> <option>选项6</option> </select>
multipleSelect.addEventListener('change', function () { result.innerHTML = this.value; });
使“选项1,选项4”选中的 JavaScript 代码示意:
button.addEventListener('click', function () { // option 元素没有设置 value 属性会把 text 作为 value 值 // 因此这里使用的是 text 文本值进行赋值,实际开发不是这样哟 multipleSelect.value = '选项1,选项4'; // value赋值不会触发change事件(和浏览器原生行为保持一致) // 需要我们手动触发 multipleSelect.dispatchEvent(new CustomEvent('change')); });
语法和参数
绝大多数场景下,大家无需关心语法和参数,也不需要初始化,直接引入 Select.js 即可。如果遇到特殊场景,下拉框没有初始化,可以使用下面的语法。
语法
element.refresh();
参数
element
参数为对应的 <select>
DOM 元素。
Select.js 下拉方法只能基于原生的 <select> 元素生成,不支持基于数据生成。如果希望基于数据结构创建下拉列表,可以参考使用 Drop.js 中的 list() 方法或者 Datalist.js。
赋值
存在特殊场景需要手动改变 <select>
元素的选中项,建议直接使用 value 赋值,下拉组件的样式会同步更新。
select.value = 'xxx';
'xxx'
是即将被选中的 <option>
元素的 value
属性值。
我们也可以直接找到对应的 <option>
元素,然后设置 selected
属性值为 true
。
以及使用设置 selectedIndex
属性值实现进行下拉选项的选中。
事件处理
本下拉组件本身只提供样式支持,至于事件处理,完全和处理原生的 <select>
下拉框一样。例如:
select.addEventListener('change', function () { console.log('来自下拉框:我变化了'); });
其他特性展示与说明
下拉定位
本组件自带下拉列表位置判断,也就是超出窗体,会自动朝上显示,例如:
元素禁用
想要实现自定义下拉控件的禁用效果,直接 <select>
元素添加 disabled
属性就可以了。例如:
<select is="ui-select" style="width:100px;" disabled> <option>请选择</option> </select>
复选框的禁用也是增加一个 disabled
属性。例如:
<select is="ui-select" multiple disabled> <option>选项1</option> <option>选项2</option> </select>
元素隐藏
如果想要隐藏(不占据空间的隐藏),可以给原生的 <select>
元素增加 HTML5 原生隐藏属性 hidden
,下拉框和后面的自定义下拉框会一并隐藏。
<select is="ui-select" hidden> <option>选项</option> </select>
元素动态添加
button.addEventListener('click', function () {
// 会自动检测到DOM变化并样式初始化
this.parentElement.insertAdjacentHTML('afterend', '<select><option>我是动态插入的</option></select> ');
});
button.addEventListener('click', function () { // 会自动检测到DOM变化并样式初始化 var option = document.createElement('option'); option.text = '我是新添加的'; option.selected = true; // 添加该option元素到最前面 select.add(option, 0); });
元素删除
button.addEventListener('click', function () {
// 会自动同步删除生成的下拉组件元素
select.parentNode.removeChild(select)
});
button.addEventListener('click', function () {
// 删除第一个option元素,同样会自动UI更新
select[0].remove();
});
可以看到,无论是初始化,事件,禁用或者添加,隐藏和删除,下拉框组件都严格遵循“面向 HTML 开发”的设计理念,也就是 Select.js 下拉所有处理都是围绕原生的 <select> 元素展开,大家千万不要对美化后的下拉框元素进行 DOM 处理。
关于大数据量时候的性能
如果遇到需要同时渲染数百或上千个下拉框的场景,需要提前对 <select>
元素通过 style
属性,或者 width
属性设置好宽度(支持数值以及任意长度单位)。可以极大地提升渲染性能,因为渲染的瓶颈就是下拉元素的宽度获取,如果提前设置好,则速度可以大大提升。
当然,常规开发完全不用在意这个细节,交互体验完全无感知。
一些限制
下拉采用的相对元素的绝对定位,列表元素在 DOM 内部,因此,如果父级存在 overflow:hidden
,可能会让下拉部分列表无法显示,这个需要注意下。
最后测试下底部边缘朝上显示:
本页贡献者:
HSDPA-wen, zhangxinxu