JavaScript几种形式的树结构菜单

yizhihongxing

下面为大家详细讲解 JavaScript 几种形式的树结构菜单的完整攻略。

什么是树结构菜单

树结构菜单是一种常见的用于网站导航或者分类展示的组件。树结构菜单的特点是可以展开、收起某一层级的菜单,同时高亮显示当前选中的菜单项。在前端开发中,我们可以使用 JavaScript 来实现这种树状结构的菜单。

JavaScript 实现树结构菜单的基本思路

在使用 JavaScript 实现树结构菜单的过程中,我们需要先获取到数据,然后根据数据生成对应的 HTML 元素,最后实现菜单的展开和收起效果。具体实现的流程如下:

1.定义数据结构: 利用JS对象来描述树形结构,例如:

let treeData = [
  {
    name: '菜单1',
    children: [
      { name: '菜单1.1', children: [] },
      { name: '菜单1.2', children: [] }
    ]
  },
  {
    name: '菜单2',
    children: [
      { name: '菜单2.1', children: [] },
      { name: '菜单2.2', children: [] }
    ]
  }
]

2.将树形结构转化为HTML结构,使用递归的方式遍历对象树,将对象属性渲染为HTML的列表项,如下所示:

function renderTree(data) {
  let ul = document.createElement('ul')
  data.forEach(item => {
    let li = document.createElement('li')
    li.innerHTML = item.name
    if(item.children && item.children.length) {
      li.appendChild(renderTree(item.children))
    }
    ul.appendChild(li)
  })
  return ul
}

3.绑定事件并实现菜单展开和收起效果,通过添加CSS类名来实现展开和收起菜单的效果,例如:

function initTree() {
  let root = document.querySelector('.tree')
  let tree = renderTree(treeData)
  root.appendChild(tree)
  // 绑定点击事件
  root.addEventListener('click', e => {
    let target = e.target
    if(target.tagName === 'LI' && target.children.length) {
      target.classList.toggle('open')
    }
  })
}

通过以上步骤,我们就可以实现一个基本的树状结构菜单。

JavaScript 实现树结构菜单的多种形式

除了基本的树状结构菜单,还可以实现以下两种形式:

1. 滑动展开效果

实现方法是:利用 CSS3 的 transition 属性给菜单添加滑动效果。

具体实现示例可以参考:https://codepen.io/eFishery/pen/VYJXGo

// JS 代码
let toggleEl = document.querySelectorAll('.tree-toggle');
let i;

for (i = 0; i < toggleEl.length; i++) {
    toggleEl[i].addEventListener('click', function(e) {
        e.preventDefault();

        let treeMenu = e.target.parentElement; //去掉最后一级的a标签
        let treeChild = treeMenu.childNodes[3];
        treeChild.classList.toggle('d-none');
        e.target.classList.toggle('fa-plus');
        e.target.classList.toggle('fa-minus');
    });
}
// CSS 代码
.tree-menu {
  list-style-type: none;
  margin: 0;
  padding: 0;
  padding-left: 20px;
}

.tree-menu li {
  position: relative;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tree-toggle {
  cursor: pointer;
  display: inline-block;
}

.d-none {
  display: none;
}

.fa-minus {
  display: none;
}

a > .fa-plus:before {
  content: "\\f067";
}

a > .fa-minus:before {
  content: "\\f068";
}

a:focus {
  outline: none;
}

.tree-menu li > .fa {
  position: absolute;
  left: -12px;
  top: 50%;
  margin-top: -10px;
}

.tree-menu > li > .fa {
  position: absolute;
  left: 0;
  top: 50%;
  margin-top: -10px;
}

.tree-menu li > ul {
  display: none;
}

.tree-menu li > ul.d-none {
  display: block;
}

.tree-menu li > ul {
  margin-top: 10px;
}

.tree-menu li > ul:before {
  content: '';
  display: block;
  border-left: 1px solid #ccc;
  bottom: 0;
  left: -20px;
  position: absolute;
  top: 0;
}

2. 搜索筛选效果

实现方法是:利用输入框输入关键词后,自动过滤不包含此关键词的菜单项。

具体实现示例可以参考:https://codepen.io/pokaworks/pen/BWYZzy

// JS 代码
// 输入框变化时执行
function onSearch(event) {
  // 搜索关键字
  // toLowerCase() 转换为小写,方便比较
  let keyword = event.target.value.trim().toLowerCase();

  // 从内存获取数据
  // 然后更新可见数据节点
  let searchRst = Search(keyword)
  if (searchRst) {
    $('#tree').empty();
    $('#tree').append(RenderVisible(searchRst));
    ExpandNode(event.target.value.trim());
  }
}

// 初始渲染visibleNodes
function RestoreNodes() {
  visibleNodes = [];
  visitedNodes = [];

  function Follow(node) {
    // 如果没访问过当前节点
    if (!visitedNodes[node.id]) {
      visitedNodes[node.id] = true;

      // 如果该节点包含我要的关键字
      if (node.title.toLowerCase().indexOf(this.keyword) > -1) {
        visibleNodes.push(node.id);
        ExpandParents(node.parentId);
      }

      // 深度优先遍历子节点
      node.children.forEach(Follow, this)
    }

  }

  this.keyword = '';
  treeData.forEach(Follow, this)
  return visibleNodes;
}

// 根据visibleNodes筛选节点
function RenderVisible(visibleNodes) {
  function Follow(node) {
    if (visibleNodes.indexOf(node.id) > -1) {
      results.push(node);
    }
  }

  var results = [];

  treeData.forEach(Follow);
  return SortNode(results);
}

// HTML 代码
<div class="form-group">
  <input type="text" 
         class="form-control" 
         placeholder="输入内容并回车搜索" 
         onblur="RestoreAll();"
         onkeyup="OnSearch(event);"/>
</div>

<div id="tree"></div>  

<script>
  $("#tree").append(RenderVisible(RestoreNodes()));
</script>

总结

通过以上的示例,我们可以看到,实现树状结构菜单的效果并不难,但其中涉及到的细节还是很多的,需要我们仔细斟酌。实际开发中,我们可以根据项目需要,选择不同的实现方式,以达到最佳效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript几种形式的树结构菜单 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 轻松理解JavaScript之AJAX

    轻松理解JavaScript之AJAX AJAX是Asynchronous JavaScript and XML的简称,意思是异步的JavaScript和XML。 AJAX的本质 AJAX的本质是通过XMLHttpRequest对象异步发送HTTP请求,获取服务器返回的数据,然后使用JavaScript操作DOM来改变页面的内容,而不用重新刷新整个页面。 A…

    JavaScript 2023年5月18日
    00
  • JS层移支示例代码

    需要讲解JS层移支的示例代码,我们先来明确一下JS层移支(JS舞台)在网页中的作用:为网站添加交互功能。那么JS层移支示例代码的完整攻略就是为网页添加交互功能的过程。 在添加交互功能之前,需要准备一个能够运行JS代码的环境,这个环境在网页中就是浏览器。在浏览器中可以使用console.log()来在控制台输出信息,这对于调试代码非常有帮助。 为了添加交互功能…

    JavaScript 2023年6月10日
    00
  • js中通过split函数分割字符串成数组小例子

    JS中通过split函数分割字符串成数组,可以帮助我们方便地对字符串进行处理,下面我们来讲解具体的攻略: 步骤1:理解split()函数 split函数是JS中字符串的一个函数,用来分割字符串,将字符串分割成一个数组。在分割字符串时,我们可以指定一个分隔符,如空格、逗号、分号等等。 步骤2:编写示例代码 下面通过两个代码示例来讲解,具体内容如下: 示例一:分…

    JavaScript 2023年5月27日
    00
  • JS删除数组里的某个元素方法

    当需要从JavaScript数组中删除某个元素时,可以使用多种不同的方法。下面是其中的几种可能的方法: 使用splice()方法 splice()方法可以用于从数组中删除一个或多个元素,这是一个十分通用的方法。splice()方法可以接受三个参数: 1.起始位置(从哪一个索引位置开始删除)。 2.要删除的元素数(要删除多少个元素)。 3.要添加的元素(可选的…

    JavaScript 2023年5月27日
    00
  • js实现prototype扩展的方法(字符串,日期,数组扩展)

    下面我将详细讲解一下“js实现prototype扩展的方法(字符串,日期,数组扩展)”的完整攻略。 什么是prototype 在 JavaScript 语言中,每个对象都可以拥有一个 prototype 属性,用于指向其原型对象。原型对象是一个普通的对象,它包含了该对象的共有属性和方法。这个原型对象本身也可以有其自己的原型,构成了原型链,从而实现了 Java…

    JavaScript 2023年5月28日
    00
  • JS中改变this指向的方法(call和apply、bind)

    JS中的函数中会有一个特殊的变量this,它代表当前函数的执行上下文。但是,由于JS是一门动态语言,函数都可以作为变量进行传递和赋值,那么函数内的this指向就可能会出现变化。在这种情况下,我们需要改变函数内this的指向,以确保函数能够正常执行。而JS中改变this指向的方法主要有三种,分别是call、apply和bind。 call call() 方法可…

    JavaScript 2023年6月10日
    00
  • JS中的BOM应用

    JS中的BOM是指浏览器对象模型,主要包括window对象、location对象、history对象、navigator对象和screen对象等。BOM提供了许多常用的操作浏览器窗口、页面跳转、获取浏览器信息等功能。下面将从以下几个方面进行详细讲解“JS中的BOM应用”的完整攻略。 1. window对象 window是BOM的核心对象,代表整个浏览器窗口。…

    JavaScript 2023年6月11日
    00
  • JavaScript实现计算器的四则运算功能

    实现计算器的四则运算功能,需要掌握一些基本的JavaScript语法。下面是实现计算器的步骤攻略: 1. HTML页面的结构设计 首先需要创建HTML结构,也就是计算器的页面UI布局,建议使用最基础的HTML结构,不使用框架,以便更好的理解JavaScript的实现过程。其中最重要的是操作符和数字按钮,结果展示部分和清除按钮。 示例代码如下: <!DO…

    JavaScript 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部