我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JS实现左侧菜单工具栏

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JS实现左侧菜单工具栏

本文实例为大家分享了JS实现左侧菜单工具栏的具体代码,供大家参考,具体内容如下

摘要

该js脚本可帮助你快速实现左侧菜单工具栏。通过js封装成一个方法类,直接new该对象即可快速生成左侧菜单工具栏。

一、效果展示 

二、menu.js文件 

(1)WenMenuNode节点

let WenMenuNode = function ({
                                text,
                                wenMenu,
                                attributes = {},
                                subs = [],
                                parentElement = null,
                                iconHTML = '',
                                level = 1,
                                parentNode = null,
                                isActive = false,
                                onLaunch = null,
                            }) {
    this._level = level;
    this._text = text;
    this._attributes = attributes;
    this._wenMenu = wenMenu;
    this._subs = subs;
    this._onLaunch = onLaunch;
    this._childHeight = 0;
    this._height = 0;
    this.style = {
        childHeight: 0,
    }
 
    this._parentElement = parentElement;
    this._parentNode = parentNode;
    this._element = this._wenMenu.createElement('li', {
        class: "wen-menu-li",
    });
    this._textElement = this._wenMenu.createElement('a', this._attributes);
    this._iconHTML = iconHTML;
    this._childNodes = [];
    this._childElement = null;
    this._activeChild = null;
    if (this._parentElement) this._parentElement.append(this._element);
    this._isActive = isActive;
    if (this._isActive) {
        if (this._level == 1) {
            this._wenMenu._activeMenu = this;
        } else if (this._parentNode) {
            this._parentNode._activeChild = this;
        }
    }
    this.create().onLaunch();
}
 
 
WenMenuNode.prototype.create = function () {
    let a = this._textElement;
    let icon = this._wenMenu.createElement('i', {
        class: "wen-menu-icon",
    })
    if (this._level > 1) {
        a.innerHTML = '<span class="wen-menu-tree">--</span>';
    }
    icon.innerHTML = this._iconHTML;
    a.append(icon);
    a.innerHTML += `<span class="wen-menu-text">${this._text}</span>`;
    if (this._level == 1) {
        a.classList.add('wen-menu-first');
    }
    this._element.append(a);
    if (this._subs.length) {
        let ul = this._wenMenu.createElement('ul', {
            class: "wen-menu-ul" + (this._level == 1 ? " wen-menu-ul-second" : ""),
        });
        this._element.append(ul);
 
        this._childElement = ul;
        this._subs.forEach((item, i) => {
            let node = new WenMenuNode({
                text: item.text,
                wenMenu: this._wenMenu,
                attributes: item.attributes,
                subs: item.subs,
                parentElement: ul,
                iconHTML: item.iconHTML,
                level: this._level + 1,
                parentNode: this,
                isActive: this._isActive && i == 0,
                onLaunch: (childNode) => {
                    this._childNodes.push(childNode);
                    if (i == this._subs.length - 1) {
                        this.setEventListener(true);
                    }
                }
            });
        });
    } else {
        this.setEventListener(false);
    }
    return this;
}
 
 
WenMenuNode.prototype.onLaunch = function () {
    if (this._onLaunch) {
        this._onLaunch.call(this._parentNode, this);
    }
    return this;
}
 
WenMenuNode.prototype.setEventListener = function (hasSub = false) {
    if (hasSub) {
        this._height = this._subs.length * this._wenMenu._menuHeight;
        this._childHeight = this._childElement.clientHeight;
        if (this._isActive) {
            this._textElement.setAttribute('wen-active', '');
            this._textElement.setAttribute('wen-expand', '');
            this.style.childHeight = this._childHeight + this._wenMenu._menuSpacing;
        } else {
            this._textElement.setAttribute('wen-icon', '')
            this._textElement.setAttribute('wen-collapse', '');
            this.style.childHeight = 0;
        }
        this._childElement.style.height = this.style.childHeight + "px";
        this._textElement.addEventListener('click', (e) => {
            if (this._wenMenu._autoCollapse) {
                this.resetHeight();
                this.setHeight({
                    menuNode: this,
                })
            } else {
                let height = 0, target = e.target;
                if (target.classList.value.indexOf('wen-menu-text') >= 0) {
                    target = target.parentElement;
                }
                if (target.getAttribute('wen-expand') === null) {
                    // todo:: 展开
                    height = this.style.childHeight = this._height + this._wenMenu._menuSpacing;
                    target.setAttribute('wen-expand', '');
                    target.removeAttribute('wen-collapse');
                } else {
                    // todo:: 收起
                    height = -this.style.childHeight;
                    this.style.childHeight = 0;
                    target.setAttribute('wen-collapse', '');
                    target.removeAttribute('wen-expand');
                    this.resetHeight(this._childNodes)
                }
                this._childElement.style.height = this.style.childHeight + 'px';
                if (this._parentNode) {
                    this.setHeight({
                        menuNode: this._parentNode,
                        direction: 'up',
                        childHeight: height,
                        childNode: this,
                    })
                }
            }
        });
    } else {
        if (this._isActive) {
            this._textElement.classList.add('wen-active');
        }
        this._textElement.addEventListener('click', (e) => {
            if (this._wenMenu._autoCollapse) {
                this.resetHeight();
                this.setHeight({
                    menuNode: this._parentNode,
                    direction: 'up',
                    childNode: this,
                    childHeight: this._height,
                })
            }
            this.removeActive(this._wenMenu._activeMenu)
            this._isActive = true;
            this._textElement.classList.add('wen-active');
            let target = e.target;
            if (target.classList.value.indexOf('wen-menu-text') >= 0) {
                target = target.parentElement;
            }
            if (target.classList.value.indexOf('wen-menu-first') >= 0) {
                this._wenMenu._activeMenu = this;
            } else if (this._parentNode) {
                this.addActive(this._parentNode, this)
            } else {
                this._wenMenu._activeMenu = this;
            }
            if (this._wenMenu._event) {
                this._wenMenu._event.call(this, e)
            }
        });
    }
    return this;
}
 
 
WenMenuNode.prototype.setHeight = function ({
                                                menuNode = null,
                                                direction = 'down',
                                                childHeight = 0,
                                                childNode = null,
                                            }) {
    if (!menuNode) {
        return 0;
    }
    menuNode._textElement.setAttribute('wen-expand', '');
    menuNode._textElement.removeAttribute('wen-collapse');
    if (this._wenMenu._autoCollapse) {
        menuNode.style.childHeight = menuNode._height;
    }
    if (direction == 'down') {
        if (menuNode._subs.length) {
            menuNode.style.childHeight += (this._wenMenu._menuSpacing * (childNode ? childNode._level : 1));
            if (menuNode._isActive) {
                menuNode.style.childHeight += this.setHeight({
                    menuNode: menuNode._activeChild,
                });
            }
            if (menuNode._childElement) {
                menuNode._childElement.style.height = menuNode.style.childHeight + "px";
            }
            if (menuNode._parentNode) {
                this.setHeight({
                    menuNode: menuNode._parentNode,
                    direction: 'up',
                    childNode: menuNode,
                    childHeight: menuNode.style.childHeight,
                });
            }
        }
    } else {
        menuNode.style.childHeight += (childHeight + this._wenMenu._menuSpacing);
        menuNode._childElement.style.height = menuNode.style.childHeight + "px";
        if (menuNode._parentNode) {
            this.setHeight({
                menuNode: menuNode._parentNode,
                direction: 'up',
                childHeight: menuNode.style.childHeight,
                childNode: menuNode,
            });
        }
    }
    return menuNode.style.childHeight;
}
 
WenMenuNode.prototype.resetHeight = function (menuNodes) {
    if (!menuNodes) {
        menuNodes = this._wenMenu._menuNodes;
    }
    menuNodes.forEach((node) => {
        if (node._childElement) {
            node.style.childHeight = 0;
            node._childElement.style.height = '0px';
        }
        if (node._childNodes.length) {
            node._textElement.setAttribute('wen-collapse', '');
            node._textElement.removeAttribute('wen-expand');
            this.resetHeight(node._childNodes);
        }
    });
    return this;
}
 
WenMenuNode.prototype.addActive = function (menuNode, activeChildNode) {
    menuNode._isActive = true
    menuNode._textElement.setAttribute('wen-active', '');
    menuNode._textElement.removeAttribute('wen-icon');
    if (this._wenMenu._autoCollapse) {
        menuNode._textElement.setAttribute('wen-expand', '');
        menuNode._textElement.removeAttribute('wen-collapse');
    }
    menuNode._activeChild = activeChildNode;
    if (menuNode._parentNode) {
        this.addActive(menuNode._parentNode, menuNode);
    } else {
        this._wenMenu._activeMenu = menuNode;
    }
    return this;
}
 

WenMenuNode.prototype.removeActive = function (menuNode) {
    menuNode._isActive = false;
    if (menuNode._subs.length) {
        menuNode._textElement.removeAttribute('wen-active');
        menuNode._textElement.setAttribute('wen-icon', '');
        if (this._wenMenu._autoCollapse) {
            menuNode._textElement.setAttribute('wen-collapse', '');
            menuNode._textElement.removeAttribute('wen-expand');
        }
        if (menuNode._activeChild) {
            this.removeActive(menuNode._activeChild);
        }
    } else {
        menuNode._textElement.classList.remove('wen-active');
    }
    return this;
}

(2) WenMenu对象 

let WenMenu = function ({
                            ele,
                            menus,
                            event = null,
                            attributes = {},
                            menuHeight = 35,
                            menuSpacing = 0,
                            autoCollapse = true,
                            duration = 300,
                        }) {
    this._ele = ele;
    this._duration = duration;
    this._menus = menus;
    this._event = event;
    this._menuNodes = [];
    this._autoCollapse = autoCollapse;
    this.style = {
        width: '100%',
        height: '100%',
    }
    this._menuElement = this.createElement('ul', attributes);
    this._menuElement.classList.value += 'wen-menu-ul wen-menu-ul-first';
    this._ele.append(this._menuElement);
    this._activeMenu = null;
    this._menuHeight = menuHeight;
    this._menuSpacing = menuSpacing;
    this.init().createStyle().createMenu();
};
 
WenMenu.prototype.init = function () {
    if (this._ele.clientHeight) {
        this._ele.style.overflow = 'hidden';
        this._menuElement.style['overflow-y'] = 'scroll';
        let scrollWidth = this._menuElement.offsetWidth - this._menuElement.clientWidth;
        this.style.width = 'calc(100% + ' + scrollWidth + 'px)';
        this.style.height = this._ele.clientHeight + 'px';
    }
    return this;
}
 

WenMenu.prototype.createMenu = function () {
    this._menus.forEach((item, i) => {
        let node = new WenMenuNode({
            text: item.text,
            attributes: item.attributes,
            subs: item.subs,
            parentElement: this._menuElement,
            wenMenu: this,
            isActive: i == 0,
        });
        this._menuNodes.push(node);
    });
    return this;
};
 

WenMenu.prototype.createElement = function (tagName, attributes = {}) {
    let ele = document.createElement(tagName);
 
    function checkValue(value) {
        if (Object.prototype.toString.call(value) === "[object Array]") {
            value = value.join(',');
        } else if (Object.prototype.toString.call(value) === '[object Object]') {
            var valueStr = '';
            Object.keys(value).forEach(function (name) {
                valueStr += name + ":" + checkValue(value[name]) + ";";
            });
            value = valueStr;
        }
        return value;
    }
 
    if (attributes) {
        Object.keys(attributes).forEach((name) => {
            let value = checkValue(attributes[name]);
            ele.setAttribute(name, value);
        })
    }
    return ele;
};
 
 
WenMenu.prototype.createStyle = function () {
    let style = this.createElement('style'),
        head = document.querySelector('head');
    style.innerHTML = `
        .wen-menu-ul-first, .wen-menu-ul-first *{
            padding: 0px;
            margin: 0px;
            border-spacing: 0px;
            list-style: none;
        }
        .wen-menu-ul-first{
            width: ${this.style.width};
            height: ${this.style.height};
        }
        .wen-menu-ul {
            overflow: hidden;
        }
        
        .wen-menu-ul-first, .wen-menu-ul-second {
            background: rgba(0, 0, 0, 0.1);
        }
        .wen-menu-li {
            padding-left: 22px;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
        }
        .wen-menu-ul-first > .wen-menu-li {
            padding: 0px;
        }
        .wen-menu-ul-second > .wen-menu-li {
            padding: 0px 0px 0px 18px;
        }
        .wen-menu-tree {
            border-left: 1px dashed rgba(0, 0, 0, 1);
            width: 16px;
        }
        .wen-menu-text{
            width: calc(100% - 16px);
            display: flex;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            -o-text-overflow: ellipsis;
        }
        .wen-menu-li a {
            display: inline-block;
            width: 100%;
            height: ${this._menuHeight}px;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            position: relative;
            cursor: pointer;
            display: flex;
            align-items: center;
        }
        .wen-menu-ul, .wen-menu-li a[wen-icon]:after, .wen-menu-li a[wen-active]:after {
            -webkit-transition: all ${this._duration}ms linear;
            -moz-transition: all ${this._duration}ms linear;
            -ms-transition: all ${this._duration}ms linear;
            -o-transition: all ${this._duration}ms linear;
            transition: all ${this._duration}ms linear;
        }
        .wen-menu-li a[wen-expand]:after {
            -webkit-transform: scale(1.3) rotate(90deg);
            -moz-transform: scale(1.3) rotate(90deg);
            -ms-transform: scale(1.3) rotate(90deg);
            -o-transform: scale(1.3) rotate(90deg);
            transform: scale(1.3) rotate(90deg);
        }
        .wen-menu-li a[wen-collapse]:after {
            -webkit-transform: scale(1.3) rotate(180deg);
            -moz-transform: scale(1.3) rotate(180deg);
            -ms-transform: scale(1.3) rotate(180deg);
            -o-transform: scale(1.3) rotate(180deg);
            transform: scale(1.3) rotate(180deg);
        }
        .wen-menu-li a[wen-icon]:after {
            content: '▷';
            position: absolute;
            right: 5px;
            font-weight: bold;
        }
        .wen-menu-li a[wen-active]:after {
            content: '▷';
            position: absolute;
            right: 5px;
            font-weight: bold;
        }
        .wen-menu-first {
            padding-left: 15px !important;
        }
        .wen-menu-li a[wen-active], .wen-active {
            color: white;
        }
        .wen-menu-li a[wen-active].wen-menu-first, .wen-active.wen-menu-first {
            border-left: 3px solid white;
        }
    `;
    if (!head) {
        head = document.body;
    }
    head.append(style);
    return this;
}

三、Example-Code

(1)html文件

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>说明文档</title>
    <script class="lazy" data-src="/js/canvas/menu.js"></script>
    <style>
        * {
            padding: 0px;
            margin: 0px;
            border-spacing: 0px;
            list-style: none;
        }
        body {
            min-height: 100vh;
            padding: 0px;
            margin: 0px;
        }
        .readme-title {
            background: rgba(0, 0, 50, 0.3);
            width: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
        }
        .readme-body {
            width: 100%;
            height: calc(100% - 75px);
            display: flex;
            justify-content: start;
        }
        .readme-menu-box {
            width: 250px;
            height: 100%;
            position: fixed;
            left: 0px;
            top: 0px;
            background: rgba(100, 10, 10, 0.2);
            overflow: auto;
        }
    </style>
</head>
<body>
<div class="readme-body">
    <div class="readme-menu-box">
        <div class="readme-title">
            <h2>目录</h2>
        </div>
    </div>
</div>
</body>
</html>

(2)JS代码

a、菜单列表

let menuOptions = [{
                    text: "导入数据列表",
                    subs: [
                        {
                            text: "全部数据",
                            attributes: {
                                "data-url": "",
                            },
                            subs: [
                                {
                                    text: "消费金额",
                                    attributes: {
                                        "data-url": "",
                                    }
                                }, {
                                    text: "放款金额",
                                    attributes: {
                                        "data-url": "",
                                    }
                                }, {
                                    text: "返佣金额",
                                    attributes: {
                                        "data-url": "",
                                    }
                                }, {
                                    text: "导入数据",
                                    attributes: {
                                        "data-url": "",
                                    }
                                }, {
                                    text: "查看",
                                    attributes: {
                                        "data-url": "",
                                    }
                                }, {
                                    text: "编辑",
                                    attributes: {
                                        "data-url": "",
                                    }
                                }
                            ]
                        }, {
                            text: "消费金额",
                            attributes: {
                                "data-url": "",
                            }
                        }, {
                            text: "放款金额",
                            attributes: {
                                "data-url": "",
                            }
                        }, {
                            text: "返佣金额",
                            attributes: {
                                "data-url": "",
                            }
                        }, {
                            text: "导入数据",
                            attributes: {
                                "data-url": "",
                            }
                        }, {
                            text: "查看",
                            attributes: {
                                "data-url": "",
                            }
                        }, {
                            text: "编辑",
                            attributes: {
                                "data-url": "",
                            }
                        }
                    ]
                }, {
                    text: "异常数据列表",
                    subs: []
                }, {
                    text: "数据修正",
                    subs: []
                }, {
                    text: "修正审核-客服经理",
                    subs: []
                }, {
                    text: "修正审核-财务",
                    subs: []
                }, {
                    text: "导入日志",
                    subs: []
                }]

b、菜单实例化 

window.onload = function () {
            new WenMenu({
                ele: document.querySelector('.readme-menu-box'), // 菜单插入的位置
                menus: menuOptions,
                event: function (e) { }, // 菜单最底端点击事件触发
                attributes: {}, // 最外层ul属性设置
                menuHeight: 35, // 每个菜单项的高度
                autoCollapse: true, // 是否自动收起无活动菜单
            })
        };

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JS实现左侧菜单工具栏

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

react怎么实现左侧菜单

react实现左侧菜单的方法:1、定义好路由结构,代码如“const Router = [{title: '',icon: 'laptop',...}]”;2、引入router文件,通过map遍历循环;3、处理一级菜单和子级菜单栏,代码如“renderSubMnenu = ({title,key,child}) => {...}”。
2023-05-14

react实现左侧菜单的方法

今天小编给大家分享的是react实现左侧菜单的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。react实现左侧菜单的方法:1、定义好路由结构,代码如“const Router =
2023-07-04

js左侧三级菜单导航实例代码

在左侧三级菜单导航想必大家都见到过吧,它的实现过程也并不复杂,下面有个不错的示例,感兴趣的朋友可以了解下
2022-11-15

Html+Css+Jquery如何实现左侧滑动拉伸导航菜单栏

这篇文章主要介绍了Html+Css+Jquery如何实现左侧滑动拉伸导航菜单栏,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。PC端移动端代码
2023-06-09

Android PopupWindow实现右侧、左侧和底部弹出菜单

本教程为大家分享了Android PopupWindow弹出菜单的具体代码,供大家参考,具体内容如下项目代码:http://xiazai.jb51.net/201611/yuanma/PopupLeftMenu(jb51.net).rar
2022-06-06

js实现下拉菜单栏

下面是一个基本的JavaScript实现下拉菜单栏的示例:HTML代码:```html菜单选项1选项2选项3```JavaScript代码:```javascriptfunction toggleMenu() {var menu = doc
2023-09-15

vue怎么实现左侧菜单树形图递归

这篇文章主要讲解了“vue怎么实现左侧菜单树形图递归”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue怎么实现左侧菜单树形图递归”吧!先说说遇到的坑,由于是子父组件,当时传递使用的是子父组
2023-07-04

js实现带菜单栏目搜索的下拉菜单

在下拉菜单栏目比较多的时候,用户查找栏目阅读会很麻烦,为了提高用户体验度,加个栏目搜索会很方便。这篇文章主要介绍了js实现带菜单栏目搜索的下拉菜单,感觉挺实用的,需要的朋友可以参考下
2022-12-22

vue中怎么实现左侧菜单和树形图递归

本文小编为大家详细介绍“vue中怎么实现左侧菜单和树形图递归”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue中怎么实现左侧菜单和树形图递归”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。效果图如下所示:先说说
2023-06-20

CSS实现侧边栏菜单特效的技巧和方法

CSS实现侧边栏菜单特效的技巧和方法近年来,随着网页设计的发展,侧边栏菜单成为了许多网页中常见的元素之一。无论是用于导航功能还是展示内容,都能给用户带来方便和更好的使用体验。本文将介绍一些常见的CSS技巧和方法,帮助你实现一个漂亮且具有特效
2023-10-24

如何使用android实现左右侧滑菜单效果的方法

这篇文章主要介绍了如何使用android实现左右侧滑菜单效果的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在android开发中,左右侧滑菜单的开发已成为我们现在开发的
2023-05-30

编程热搜

目录