使用class封装简约Select下拉选择器
功能:
-
获取选择器的选中value,label
-
设置选择器的选中值
-
清空选择器选中值
效果图:
css代码:
.wind_select {
position: relative;
width: 100%;
height: 30px;
box-sizing: border-box;
border-radius: 4px;
border: 1px solid #dcdfe6;
color: #606266;
z-index: 2;
}
.wind_select svg {
position: absolute;
top: 50%;
right: 8px;
transform: translateY(-50%);
z-index: 1;
transform-origin: center center;
width: 16px;
height: 16px;
transition: all 0.5s;
}
.wind_select_input {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: 1px 11px;
padding-right: 30px;
box-sizing: border-box;
border: none;
outline: none;
touch-action: manipulation;
cursor: pointer;
color: #606266;
border-radius: 4px;
background-color: transparent;
z-index: 2;
font-size: 15px;
line-height: 40px;
}
.wind_select li {
list-style: none;
}
.wind_select_cont {
display: none;
position: absolute;
width: 100%;
background-color: #fff;
box-sizing: border-box;
border: 1px solid #e4e7ed;
border-radius: 4px;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
padding: 5px 0;
}
.wind_select_cont_top {
left: 50%;
bottom: 140%;
transform: translateX(-50%);
}
.wind_select_cont_bottom {
left: 50%;
top: 140%;
transform: translateX(-50%);
}
.wind_select_cont::after {
content: 1;
}
.wind_select_ul {
width: 100%;
height: auto;
max-height: 200px;
overflow-y: auto;
margin: 0 auto;
}
.wind_select_ul .active {
color: #409eff;
}
.wind_select_ul::-webkit-scrollbar {
width: 6px;
}
.wind_select_ul::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #dedfe1;
}
.wind_select_cont li {
line-height: 40px;
box-sizing: border-box;
padding: 0 10px;
background-color: #fff;
cursor: pointer;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
}
.wind_select_cont li:hover {
background-color: #f5f7fa;
}
@keyframes fadeInDown {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.wind_select_fadeInDown {
animation: fadeInDown 0.4s ease-in;
}
js封装class类
class wind_Select {
constructor(options) {
//放入的容器的id
this.el_id = options.el_id;
//默认提示文字
this.placeholderText = options.placeholderText || "请选择";
//原始数据
this.list = options.list || [];
//选中的数据
this.value = options.value || "";
//选中的label
this.select_label = "";
//数据配置
this.config = {
label: options.config.label || "label", //展示数据的label
value: options.config.value || "value", //展示数据的value
};
// 创建下拉选择框
this.create();
}
//初始化
create() {
// 创建主体
const select = document.createElement("div");
let list_el = ""; //下拉框的数据
this.list.forEach((item) => {
if (item[this.config.value] == this.value) {
list_el += ` <li class="active" data-val=${item[this.config.value]}>${
item[this.config.label]
}</li>`;
this.select_label = item[this.config.label];
} else {
list_el += ` <li data-val=${item[this.config.value]}>${
item[this.config.label]
}</li>`;
}
});
select.setAttribute("class", "wind_select");
select.innerHTML = ` <input
class="wind_select_input"
readonly
autocomplete="off"
type="text"
placeholder="${this.placeholderText}"
/>
<div class="wind_select_cont">
<ul class="wind_select_ul">
${list_el}
</ul>
</div>
<svg t="1689821864061" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2277" width="64" height="64"><path d="M958.009 307.2c0-9.317-3.554-18.636-10.663-25.746-14.219-14.218-37.273-14.218-51.491 0l-383.854 383.856-383.854-383.856c-14.219-14.218-37.271-14.218-51.49 0-14.219 14.22-14.219 37.271 0 51.491l409.6 409.6c14.219 14.218 37.271 14.218 51.49 0l409.6-409.6c7.109-7.11 10.663-16.429 10.663-25.746z" p-id="2278" fill="#dcdfe6"></path></svg>
`;
document.querySelector(`#${this.el_id}`).appendChild(select); //放入父级结构
document.querySelector(`#${this.el_id} .wind_select_input`).value =
this.select_label;
document.querySelector(`#${this.el_id} .wind_select_input`).onfocus =
this.inputFocus.bind(this);
document.querySelector(`#${this.el_id} .wind_select_input`).onblur =
this.inputBlurs.bind(this);
document
.querySelectorAll(`#${this.el_id} .wind_select_ul li`)
.forEach((item) => {
item.onmousedown = this.itemClick.bind(this, item);
});
}
//更新值
setValue(val) {
let indexs = -1;
this.list.forEach((item, index) => {
//有这个值就赋值
if (item[this.config.value] == val) {
indexs = index;
this.value = val;
this.select_label = item[this.config.label];
document.querySelector(`#${this.el_id} .wind_select_input`).value =
this.select_label;
}
});
//重新更新一下UI
if (indexs > -1) {
document
.querySelectorAll(`#${this.el_id} .wind_select_ul li`)
.forEach((item) => {
item.classList.remove("active");
});
document
.querySelectorAll(`#${this.el_id} .wind_select_ul li`)
[indexs].classList.add("active");
}
}
//获取值
getValue(callback) {
callback({
label: this.select_label,
value: this.value,
});
}
//清空值
clearValue() {
this.value = "";
this.select_label = "";
document
.querySelectorAll(`#${this.el_id} .wind_select_ul li`)
.forEach((item) => {
item.classList.remove("active");
});
document.querySelector(`#${this.el_id} .wind_select_input`).value =
this.select_label;
}
// 输入框获取焦点事件;
inputFocus() {
var rect = document.querySelector(`#${this.el_id}`).getBoundingClientRect(); //获取元素距离底部距离
var distanceToBottom = window.innerHeight - rect.bottom;
if (distanceToBottom < 300) {
document
.querySelector(`#${this.el_id} .wind_select_cont`)
.classList.add("wind_select_cont_top");
document
.querySelector(`#${this.el_id} .wind_select_cont`)
.classList.remove("wind_select_cont_bottom");
} else {
document
.querySelector(`#${this.el_id} .wind_select_cont`)
.classList.remove("wind_select_cont_top");
document
.querySelector(`#${this.el_id} .wind_select_cont`)
.classList.add("wind_select_cont_bottom");
}
document
.querySelector(`#${this.el_id} .wind_select_cont`)
.classList.add("wind_select_fadeInDown");
document.querySelector(`#${this.el_id} .wind_select_cont`).style.display =
"block";
document.querySelector(`#${this.el_id} .wind_select svg`).style.transform =
"translateY(-50%) rotate(-180deg)";
}
// 输入框失去焦点事件;
inputBlurs() {
document.querySelector(`#${this.el_id} .wind_select_cont`).style.display =
"none";
document.querySelector(`#${this.el_id} .wind_select svg`).style.transform =
"translateY(-50%) rotate(0deg)";
}
//下拉框每项点击事件
itemClick(el) {
document
.querySelectorAll(`#${this.el_id} .wind_select_ul li`)
.forEach((item) => {
item.classList.remove("active");
});
el.classList.add("active");
this.value = el.getAttribute("data-val");
this.select_label = el.innerText;
document.querySelector(`#${this.el_id} .wind_select_input`).value =
this.select_label;
}
}
使用
<!-- 展示节点 -->
<div id="mys_box" style="width: 200px"></div>
<div style="margin-top: 50px; display: flex; justify-content: center">
<button onclick="sets()">设置值</button>
<button onclick="gets()">获取选中值</button>
<button onclick="clears()">清空选中值</button>
</div>
const my_Select = new wind_Select({
el_id: "mys_box", //插入的展示节点id
//数据列表
list: [
{
label: "第一个",
value: 1,
},
{
label: "第二个",
value: 2,
},
{
label: "第三个",
value: 3,
},
{
label: "第四个",
value: 4,
},
{
label: "第五个",
value: 5,
},
{
label: "第六个",
value: 6,
},
],
config: {
label: "label", //下拉框需要展示的label
value: "value", //下拉框选中的数据
},
value: 2, //默认值 可不选
placeholderText: "请选择数据", //下拉选择器提示文字
});
function sets() {
my_Select.setValue(3); //下拉选择器设置值方法
}
function gets() {
my_Select.getValue((res) => {
//下拉选择器获取选中的值和label
console.log(res);
});
}
function clears() {
//清空下拉选择器的值
my_Select.clearValue();
}