作为插件单独使用
引入CSS:
<link rel="stylesheet" href="https://qidian.gtimg.com/lulu/pure/css/common/ui/Select.css">
引入JS:
<script src="https://qidian.gtimg.com/lulu/pure/js/common/ui/Select.js"></script>
下拉框-单选
为空
没有任何 <option> 元素。
<select></select>
label赋值
如果设置了 label 属性,优先使用 label 属性值作为列表值。
此时,<option> 元素内的值会被忽略。
<select id="select">
<option value="1" label="选项a">选项1</option>
<option value="2" label="选项b">
</select>
赋值
测试禁用态样式,以及动态赋值与样式同步变化。
<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; }); // 不推荐,因为需要手动refresh() button.addEventListener('click', function () { select[1].selected = true; // 需要手动触发刷新 select.refresh(); });
和浏览器原生行为一样,value 赋值不会触发 change 事件。
隐藏
button.addEventListener('click', function () {
select.setAttribute('hidden', '');
});
滚动条
主要测试记住上一次滚动条位置的细节。
分组
支持<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>
宽度外部自适应
有时候,我们需要 <select> 元素宽度100%自适应外部容器,可以通过添加 width="100%" 快捷设置。
<select width="100%">
<option>选项1</option>
<option>选项2</option>
</select>
通过 width 属性提前设置好宽度有助于提高性能,但是除了 100% 以外的其他值对应CSS并未设置,会出现原始 <select> 和美化的下拉元素宽度不一致的场景出现。
例如希望 <select> 宽度 50%,则要么 CSS 中自己设置下。
select[width="50%"] {
width: 50%;
}
要么使用 style 属性设置,例如:
<select style="width: 50%">
下拉框-复选
请选择:
选中的结果是:选项2, 选项3
<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 即可。
<script src="/path/common/ui/Select.js"></script>
如果遇到特殊场景,下拉框没有初始化,可以使用下面的语法。
语法
new Select(element);
或者
element.refresh();
参数
element 参数为对应的 <select> DOM元素。
Select.js 下拉方法只能基于原生的 <select> 元素生成,不支持基于数据生成。如果希望基于数据结构创建下拉列表,可以参考使用 Drop.js 中的 list() 方法 或者 Datalist.js。
赋值
存在特殊场景需要手动改变 <select> 元素的选中项,建议直接使用 value 赋值,下拉组件的样式会同步更新。
select.value = 'xxx';
'xxx' 是即将被选中的 <option> 元素的 value 属性值。
当然,我们也可以直接找到对应的 <option> 元素,然后设置 selected=true,但是需要注意的是,我们需要手动 refresh 下:
select.refresh();
事件处理
本下拉组件本身只提供样式支持,至于事件处理,完全和处理原生的 <select> 下拉框一样。例如:
select.addEventListener('change', function () {
console.log('来自下拉框:我变化了');
});
其他特性展示与说明
使用原生下拉框
给 <select> 元素设置 is-visible 属性,则 Select.js 不会美化此下拉框,采用原生的 UI。
<select is-visible>
<option>选项1</option>
<option>选项2</option>
</select>
<select is-visible class="error">
<option>出错示意</option>
<option>选项1</option>
<option>选项2</option>
</select>
原生下拉框可以在移动端使用。
下拉定位
本组件自带下拉列表位置判断,也就是超出窗体,会自动朝上显示,例如:
元素禁用
想要实现自定义下拉控件的禁用效果,直接 <select> 元素添加 disabled 属性就可以了。例如:
<select style="width:100px;" disabled>
<option>请选择</option>
</select>
复选框的禁用也是增加一个 disabled 属性。例如:
<select multiple disabled>
<option>选项1</option>
<option>选项2</option>
</select>
元素隐藏
如果想要隐藏(不占据空间的隐藏),可以给原生的 <select> 元素增加 HTML5 原生隐藏属性 hidden,下拉框和后面的自定义下拉框会一并隐藏。
<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 id="bi" class="ui-button" data-type="primary">插入form带select</button>
bi.addEventListener('click', function () {
this.insertAdjacentHTML('afterend', '<form><select><option>请选择</option></select><form>');
});
元素删除
button.addEventListener('click', function () {
// 会自动同步删除生成的下拉组件元素
select.parentNode.removeChild(select)
});
button.addEventListener('click', function () {
// 删除第一个option元素,同样会自动UI更新
select[0].remove();
});
可以看到,无论是初始化,事件,禁用或者添加,隐藏和删除,下拉框组件都严格遵循“面向HTML开发”的设计理念,也就是 Select.js 下拉所有处理都是围绕原生的 <select> 元素展开,大家千万不要对美化后的下拉框元素进行行为上的处理。
关于大数据量时候的性能
如果遇到需要同时渲染数百或上千个下拉框的场景,需要提前对 <select> 元素通过 style 属性,或者 width 属性设置好宽度(支持数值以及任意长度单位)。可以极大地提升渲染性能,因为渲染的瓶颈就是下拉元素的宽度获取,如果提前设置好,则速度可以大大提升。
当然,常规开发完全不用在意这个细节,交互体验完全无感知。
最后测试下底部边缘朝上显示:
本页贡献者:
zhangxinxu