JavaScript几种形式的树结构菜单

下面为大家详细讲解 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日

相关文章

  • Bootstrap Table的使用总结

    Bootstrap Table的使用总结 Bootstrap Table是一个基于Bootstrap的jQuery插件,它可以将一个普通的HTML表格转化成一个功能丰富的高级表格,支持分页、排序、搜索、多选等功能。在前端开发中,Bootstrap Table常常被用来展示比较复杂的数据集,它简单易用,功能强大,可以大大提升用户体验。 安装 要使用Bootst…

    JavaScript 2023年6月10日
    00
  • js对象浅拷贝和深拷贝详解

    JS对象浅拷贝和深拷贝详解 在JavaScript中,对象是非常重要的数据类型,它允许我们用键值对的形式来表示和存储数据。当我们需要复制一个对象时,需要了解什么是浅拷贝和什么是深拷贝。本文将详细解释这两种拷贝方式,并提供实例进行说明。 什么是浅拷贝 浅拷贝是指复制出来的新对象的属性是源对象的引用,而不是属性值的拷贝。也就是说,当源对象属性的值为对象或数组时,…

    JavaScript 2023年5月27日
    00
  • JavaScript 中的 parseInt() 函数详解

    JavaScript 中的 parseInt() 函数详解 什么是 parseInt() 函数? parseInt() 是 JavaScript 内置的一个函数,用于将字符串解析成整型数字。该函数的作用是从字符串中提取数字,将其转换为十进制整数。 parseInt() 函数的语法 parseInt() 函数的语法格式如下: parseInt(string, …

    JavaScript 2023年5月27日
    00
  • jQuery 快速结束当前正在执行的动画

    jQuery 提供了 stop() 方法用于快速结束当前正在执行的动画,其语法为: $(selector).stop(stopAll, goToEnd); 其中 stopAll 参数用于控制是否停止正在队列中等待执行的动画,默认为 false,即仅结束当前正在执行的动画。goToEnd 参数用于控制是否立即完成动画至结尾状态,默认为 false,即立即结束。…

    JavaScript 2023年6月11日
    00
  • javascript开发随笔一 preventDefault的必要

    JavaScript开发随笔一:preventDefault的必要 在JavaScript开发中,我们经常会用到一些DOM操作,例如点击超链接跳转页面,提交表单等。但是有些时候,我们可能会需要改变这些默认行为,比如说:阻止页面跳转,防止表单提交。 这个时候,我们就需要用到事件对象的preventDefault()方法。这个方法可以阻止元素默认的行为,从而实现…

    JavaScript 2023年6月11日
    00
  • js前端传json后台接收‘‘被转为quot的问题解决

    当前端使用 JavaScript 将 JSON 对象发送到后台时,有时可能会遇到 JSON 字符串中的双引号被转换为 &quot; 实体的问题,这可能会导致后端无法正确解析 JSON 字符串的情况。下面是解决这个问题的攻略: 1. 从前端开始 首先,确保前端代码正确地生成了 JSON 字符串,不应该使用任何 HTML 实体序列化。例如,以下代码可能会…

    JavaScript 2023年5月27日
    00
  • JavaScript 正则应用详解【模式、欲查、反向引用等】

    JavaScript 正则应用详解【模式、欲查、反向引用等】攻略 正则表达式是用来描述或者匹配一些字符串模式的工具。JavaScript 支持正则表达式,可以使用正则表达式进行字符串的匹配、查找、替换、拆分等操作。本文将详细介绍 JavaScript 正则表达式的常用应用。 一、正则表达式概述 正则表达式是一种字符模式,用于匹配或识别一些特定的字符串模式。正…

    JavaScript 2023年5月27日
    00
  • JavaScript中的LHS和RHS分析详情

    LHS和RHS分析是 JavaScript 引擎在编译或执行期间的一个步骤,用于寻找变量的值或将值赋给变量。这里的LHS和RHS代表了赋值操作(Assignment)的左值和右值。其中LHS用于对变量的赋值操作进行操作,而RHS用于对变量取值操作进行操作。 LHS查找 LHS查找是指寻找变量的容器(Container),即变量本身。在执行代码时,如果发现变量…

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