js开关菜单

开关菜单

/* 
    将需要的信息添加到类的静态数组里备用 
    设置一个值openBool,默认为false;菜单默认display为none
    点击时,如果目标元素是子元素,则不做开关菜单操作,直接return。
    点击时,读取openbool。
    bool为false,打开菜单;bool为true时,关闭菜单。每次执行菜单操作之后,bool取反。循环往复。
*/
import Utils from "./Utils.js";
export default class ProClassify {

    static proList = [
        { id: 1, class: "diamondClass", name: "钻石", item: ["GIA钻石", "30分钻石", "50分钻石", "北极光钻石"] },
        { id: 2, class: "ringClass", name: "钻戒", item: ["铂金钻戒", "30分钻戒", "50分钻戒", "70分钻戒", "克拉钻戒"] },
        { id: 3, class: "doubleRingClass", name: "对戒", item: ["铂金对戒", "18K对戒"] },
        { id: 4, class: "ornamentClass", name: "配饰", item: ["吊坠", "耳钉", "套链", "项链", "手链"] },
    ];
constructor() {
this.elem = this.createElem(); }

createElem() { let con = document.createDocumentFragment(); ProClassify.proList.map(proItem => { let div = document.createElement("div"); div.className = "classItem"; div.innerHTML = ` <li id="${proItem.class}" class="${proItem.class}">${proItem.name} <ul> ${ proItem.item.reduce((total, cur) => { return total + `<a href="###">${cur}</a>`; }, "") } </ul> </li>`; //将id下的所有子元素添加到this Utils.getIdElem(div, this); div.openBool = false; this[proItem.class].addEventListener("click", e => this.liClickHandler(e)); con.appendChild(div); }); return con; } //点击开关菜单 liClickHandler(e) { if (e.target.constructor === HTMLAnchorElement) return; e.target.children[0].style.display = e.target.parentNode.openBool ? "none" : "block"; e.target.parentNode.openBool = !e.target.parentNode.openBool; } //插入父容器最前位置,bool为true则添加到末尾 unShiftIn(parent,bool) { parent = HTMLElement.isPrototypeOf(parent.constructor) ? parent : document.querySelector(parent); if (parent) bool ? parent.appendChild(this.elem) : parent.insertBefore(this.elem, parent.firstChild); } }

Utils

export default class Utils{
    //将id下的所有子元素添加到this
    static getIdElem(elem,o){
        if(elem.id) o[elem.id]=elem;
        if(elem.children.length===0) return o;
        for(var i=0;i<elem.children.length;i++){
            Utils.getIdElem(elem.children[i],o);
        }
    }
}

效果:

 开:

 

关:

后记

display:none不占位置,不在文档流中,导致transition失效。考虑动画或者visibility+定位实现

多级菜单:考虑用递归,关闭父菜单关闭时维护其所有子菜单的开关状态、openBool值。

猜你喜欢

转载自www.cnblogs.com/ltfxy/p/12378505.html