三级级联式菜单

1、组件式开发三级级联式菜单
2、实现通信
3、数据驱动渲染生成下拉菜单内容
4、访问器属性动态更改数据进行数据驱动渲染生成

菜单块组件代码如下:
export default class threeMenu extends EventTarget{
name;
elem;
ul;
span;
_showData=[];
_bool=false;
constructor(_name){
    super();
    this.name=_name;
    this.elem=this.createElem();
}
createElem(){
    if(this.elem) return this.elem;
    let div =document.createElement("div");
    div.addEventListener("click",e=>this.clickHandler(e));
    Object.assign(div.style,{
        float:"left",
        marginRight:5+"px"
    })
    this.createDiv(div);
    return div;
}
appendTo(parent) {
    if (typeof parent === "string") parent = document.querySelector(parent);
    parent.appendChild(this.elem);
}
createDiv(parent){
    this.span=document.createElement("span");
    this.ul=document.createElement("ul");
 
    Object.assign(this.span.style,{
        width:80+"px",
        height:20+"px",
        display:"block",
        marginLeft:9+"px",
        marginTop:4+"px",
        textAlign:"center",
        border:"1px solid black",
        cursor:"pointer"
    });
    
    Object.assign(this.ul.style,{
        width:60+"px",
        marginTop:6+"px",
        textAlign:"center",
    });

    parent.appendChild(this.span);
    parent.appendChild(this.ul);
    this.createList(this.ul);
    
}
createList(parent){
    var box=document.createDocumentFragment();
    this._showData.forEach(item=>{
        this.elem.lastElementChild.innerHTML="";
        var li=document.createElement("li");
        Object.assign(li.style,{
            listStyle:"none",
            height:20+"px",
            lineHeight:20+"px",
            width:80+"px",
            marginLeft:-31+"px",
            border:"1px solid #000000",
            cursor:"pointer"
        });
        li.innerHTML=item;
        box.appendChild(li);
    });
    parent.appendChild(box);
    this.span.innerHTML=this._showData[0];
    this.ul.style.display="none";
}
clickHandler(e){
    this.bool=!this.bool;
    if(e.target.nodeName==="LI"){
        this.elem.firstElementChild.textContent="";
        this.elem.firstChild.textContent=e.target.textContent;
        var evt=new Event("change");
        evt.data=this.elem.firstChild.textContent;
        evt.name=this.name;
        this.dispatchEvent(evt);
    }
}
// 访问器属性动态更改数据
set showData(value){
    this._showData=value;
    this.createList(this.ul);
    this._bool=false;
}
get showData(){
    return this._showData;
}
//访问器属性方法实现菜单的下拉与收回
set bool(value){
    if(value){
        this.elem.lastElementChild.style.display="block";
    }else{
        this.elem.lastElementChild.style.display="none";
    }
    this._bool=value;
}
get bool(){
    return this._bool;
 }
}

html页面代码实现如下:
1、AJAX与后端通信获取数据
2、通过设置访问器属性动态更改数据实现数据驱动生成菜单
3、抛发事件抛出change事件再次通信获取数据渲染生成新的菜单

    import threeMenu from "./threeMenu.js";
    import QueryString from "./js/QueryString.js";
    var provinceArr,cityArr,countyArr;
    var province,city,county;
    init();
    function init(){
        render();
        ajax("province");
    }

    function render(){
        province=new threeMenu("province");
        province.addEventListener("change",changeHandler);
        province.appendTo("body");

        city=new threeMenu("city");
        city.addEventListener("change",changeHandler);
        city.appendTo("body");

        county=new threeMenu("county");
        county.addEventListener("change",changeHandler);
        county.appendTo("body");
    }
    
    function changeHandler(e){
        switch(e.name){
            case "province":
                ajax("city",{province:e.data});
                break;
            case "city":
                var currentPro=province.elem.firstElementChild.textContent.trim();
                ajax("county",{
                    province:currentPro,
                    city:e.data
                });
                break;
        }
    }
     // ajax GET方式请求通信
    function ajax(type,data){
        if(data===undefined) data="";
        data=QueryString.stringify(data);
        var xhr=new XMLHttpRequest();
        xhr.addEventListener("load",loadHandler);
        xhr.open("GET","http://10.9.72.223:4010/"+type+"/?"+data);
        xhr.send();
    }

    // 通信完成后将返回来的数据信息进行处理
    function loadHandler(e){
        var xhr=e.currentTarget;
        xhr.removeEventListener("load",loadHandler);
        var type=xhr.responseURL.trim().split("?")[0];
        if(type.slice(-1)==="/") type=type.slice(0,-1);
        type=type.split("/").pop();
        var o=JSON.parse(xhr.response);
        switch(type){
            case "province":
                provinceArr=o;
                ajax("city",{
                    province:provinceArr[0]
                });
                province.showData=provinceArr;
                break;
            case "city":
                cityArr=o;
                var currentPro=province.elem.firstElementChild.textContent.trim();
                ajax("county",{
                    province:currentPro,
                    city:cityArr[0]
                });
                city.showData=cityArr;
                break;
            case "county":
                countyArr=o;
                county.showData=countyArr;
                break;
        }
        
    }
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值