原生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>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

效果展示正常,基本符合我的预期,接下来需要的功能还可以在添加上,比如滚动框样式等等。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值