用原生js封装实现下拉框小插件
下拉框插件
- 原生下拉框实在是不太美观,各大框架也有自己的下拉框插件,今天我们自己用面向对象的方法来实现一下。有哪些不恰当的地方欢迎各位前来讨论。
- 以下是效果图:
导入js
首先说一下封装过程中导入的两个js:Utils.js和BaseElement.js.分别利用了里面的创建Element和初始化js。
import BaseElement from "./BaseElement.js";
import Utils from "./Utils.js"
接下来就是代码部分
export default class Menu extends BaseElement{
//定义相关变量
height=34;
value="";
pre;
preLi;
arr;
leftBn;
rightBn;
constructor(){
super();
this.elem.addEventListener("mouseleave",e=>this.leaveHandler(e));
this.createButton();
this.createMenuList();
this.elem.style.height=this.height+10+"px";
}
//创建容器
createElem(){
if(this.elem) return this.elem;
return Utils.ce("div",{
positive:"relative"
})
}
//在这里设置左侧内容显示框和右侧的按钮
createButton(){
let div=Utils.ce("div",{
position:"absolute"
})
this.leftBn=Utils.ce("div",{
height:this.height+"px",
padding:"0 15px",
lineHeight:this.height+"px",
fontSize:"14px",
border:"1px solid #cccccc",
borderTopLeftRadius:"6px",
borderBottomLeftRadius:"6px",
float:"left"
});
this.rightBn=Utils.ce("div",{
height:this.height+"px",
padding:"0 8px",
lineHeight:this.height+"px",
fontSize:"14px",
border:"1px solid #cccccc",
borderTopRightRadius:"6px",
borderBottomRightRadius:"6px",
borderLeft:"none",
float:"left"
})
var caret=Utils.ce("span",{
width:0,
margin:0,
display:"block",
marginTop:"15px",
borderTop:"5px solid #000000",
borderLeft:"5px solid transparent",
borderRight:"5px solid transparent"
});
this.rightBn.appendChild(caret);
div.appendChild(this.leftBn);
div.appendChild(this.rightBn);
//添加事件侦听,在下方写入相关逻辑
this.leftBn.addEventListener("mouseover",e=>this.mouseHandler(e));
this.leftBn.addEventListener("mouseout",e=>this.mouseHandler(e));
this.leftBn.addEventListener("mousedown",e=>this.mouseHandler(e));
this.leftBn.addEventListener("click",e=>this.mouseHandler(e));
this.rightBn.addEventListener("mouseover",e=>this.mouseHandler(e));
this.rightBn.addEventListener("mouseout",e=>this.mouseHandler(e));
this.rightBn.addEventListener("mousedown",e=>this.mouseHandler(e));
this.rightBn.addEventListener("click",e=>this.mouseHandler(e));
div.addEventListener("mouseleave",e=>this.mouseHandler(e))
this.elem.appendChild(div);
}
mouseHandler(e){
if(e.type==="mouseover"){
e.currentTarget.style.backgroundColor="#cccccc";
}else if(e.type==="mouseout") e.currentTarget.style.backgroundColor="#FFFFFF";
else if(e.type==="mousedown"){
if(this.pre)this.pre.style.boxShadow="none";
this.pre=e.currentTarget;
//鼠标移动上去的时候出发mouseover,backgroundColor为灰色,在这里为他设置为白色
this.pre.style.backgroundColor="#FFFFFF";
this.pre.style.boxShadow="3px 3px 3px #CCCCCC inset";
}
else if(e.type==="mouseleave"){
if(!this.pre) return;
this.pre.style.boxShadow="none";
}
else if(e.type==="click") this.list.style.display="block";
}
createMenuList(){
this.list=Utils.ce("ul",{
listStyle:"none",
margin:0,
padding:0,
position:"absolute",
display:"none",
maxHeight:"300px",
overflow:"auto",
top:this.height+10+"px",
border:"1px solid #CCCCCC",
boxShadow:"3px 3px 3px #cccccc"
});
this.list.addEventListener("click",e=>this.listHandler(e));
this.list.addEventListener("mouseover",e=>this.listHandler(e));
this.elem.appendChild(this.list);
}
setData(_arr){
this.arr=_arr;
this.list.innerHTML="";
for(var i=0;i<this.arr.length;i++){
let li=Utils.ce("li",{
padding:"3px 30px",
margin:"2px 0"
})
this.list.appendChild(li)
li.textContent=this.arr[i];
}
//设置文字显示框的默认值
this.selectedItem(this.list.children[0]);
}
listHandler(e){
if(e.target.constructor!==HTMLLIElement) return;
//不要忘记添加pre判断,这个模块多处需要
if(e.type==="mouseover"){
if(this.preLi){
this.preLi.style.backgroundColor="#FFFFFF";
}
this.preLi=e.target;
this.preLi.style.backgroundColor="#CCCCCC"
}
//点击后让左侧文本显示栏显示选中文字
else if(e.type==="click") this.selectedItem(e.target);
}
leaveHandler(e){
this.list.style.display="none";
}
//单击下拉列表后,将选中内容在文本显示区域显示,同时下拉列表隐藏
selectedItem(li){
this.leftBn.textContent=li.textContent;
this.list.style.display="none";
this.value=li.textContent;
var evt=new Event("change");
evt.selectContent=this.leftBn.textContent;
evt.selectIndex=Array.from(this.list.children).indexOf(li);
this.dispatchEvent(evt);
}
}
对象封装完了之后测试下
<script type="module">
import Menu from "./js/Menu.js";
let arr=["北京","西安","洛阳","开封","安阳","南京","杭州","扬州","天津","青岛"];
let menu=new Menu();
menu.addEventListener("change",changeHandle);
menu.appendTo("body");
menu.setData(arr);
function changeHandle(e){
console.log(e)
}
</script>
效果展示正常,基本符合我的预期,接下来需要的功能还可以在添加上,比如滚动框样式等等。