JavaScript树形组件实现无限级树形结构

以下是“JavaScript树形组件实现无限级树形结构”的完整攻略。

什么是树形结构?

树形结构是计算机科学中非常常见的一种数据结构,它类似于现实生活中的树,由一个根节点和多个子节点组成。树形结构具有递归的性质,每个节点都可以看作一个子树。

树形结构在网站中的应用

在网站中,我们会经常遇到需要展示树形结构的场景,比如商品分类、组织架构、地区选择等。为了方便展示和交互,我们需要实现一个树形组件,可以无限级别地展开和收起节点。

如何实现无限级树形结构?

要实现无限级树形结构,我们需要做以下几步:

1. 准备数据

首先要准备好树形结构的数据。一个节点包含有唯一ID、父节点ID、节点名称等信息。通常,我们采用数组或者JSON格式来描述树形结构。示例数据如下:

[
  { id: 1, name: '节点1', parentId: null },
  { id: 2, name: '节点2', parentId: 1 },
  { id: 3, name: '节点3', parentId: 1 },
  { id: 4, name: '节点4', parentId: 2 },
  { id: 5, name: '节点5', parentId: 2 },
  { id: 6, name: '节点6', parentId: 4 },
  { id: 7, name: '节点7', parentId: 5 },
  { id: 8, name: '节点8', parentId: 3 }
];

2. 递归生成DOM节点

接下来,我们需要根据数据递归生成DOM节点,将节点插入到对应的父节点中。示例代码如下:

function buildTree(data, parent) {
  let ul = document.createElement('ul');
  parent.appendChild(ul);

  data.forEach(function(node) {
    if (node.parentId === parent.dataset.id) {
      let li = document.createElement('li');
      let title = document.createElement('div');
      title.innerText = node.name;
      // 点击标题展开或者收起子节点
      title.onclick = function() {
        li.classList.toggle('expand');
      };

      li.appendChild(title);
      ul.appendChild(li);
      buildTree(data, li);
    }
  });
}

let root = document.getElementById('root');
buildTree(data, root);

在上面的示例中,我们使用HTML的ulli元素来实现树形结构。对于每一个节点,我们创建一个包含标题和子节点ulli元素,插入到对应的父节点ul中。通过递归调用buildTree函数,我们可以遍历整个数据,生成完整的树形结构。

3. 添加样式和交互效果

最后,我们需要添加样式和交互效果,使树形结构更加美观和易用。比如,当用户点击标题的时候,展开或者收起相应的子节点;添加展开、收起、选中等功能按钮。

示例代码如下:

.tree li {
  list-style: none;
  position: relative;
  padding-left: 20px;
  line-height: 20px;
}

.tree li::before, .tree li::after {
  content: '';
  position: absolute;
  left: -10px;
  top: 0;
  height: 100%;
  border-left: 1px solid #ccc;
}

.tree li::before {
  border-bottom: 1px solid #ccc;
  transform: translateX(-50%);
}

.tree li::after {
  transform: translateX(-50%) rotate(-90deg);
}

.tree li:last-child::before {
  border-left: none;
}

.tree li.expand::after {
  transform: translateX(-50%) rotate(0);
}

.tree li .btn {
  position: absolute;
  left: 0;
  top: 0;
  width: 20px;
  height: 20px;
  line-height: 20px;
  text-align: center;
  font-size: 12px;
  cursor: pointer;
}

.tree li.selected {
  background-color: #eee;
}
// 添加交互效果和按钮
function buildTree(data, parent) {
  let ul = document.createElement('ul');
  parent.appendChild(ul);
  ul.classList.add('tree');

  data.forEach(function(node) {
    if (node.parentId === parent.dataset.id) {
      let li = document.createElement('li');
      let title = document.createElement('div');
      title.innerText = node.name;
      title.classList.add('title');

      let btnExpand = document.createElement('span');
      btnExpand.innerText = '+';
      btnExpand.classList.add('btn', 'expand');
      btnExpand.onclick = function(event) {
        event.stopPropagation();
        li.classList.toggle('expand');
      };
      title.appendChild(btnExpand);

      let btnSelect = document.createElement('span');
      btnSelect.innerText = '√';
      btnSelect.classList.add('btn', 'select');
      btnSelect.onclick = function(event) {
        event.stopPropagation();
        li.classList.toggle('selected');
      };
      title.appendChild(btnSelect);

      li.appendChild(title);
      ul.appendChild(li);
      li.dataset.id = node.id;
      buildTree(data, li);
    }
  });
}

let root = document.getElementById('root');
buildTree(data, root);

在上面的示例代码中,我们定义了一些CSS样式,包括节点样式、节点连接线样式、按钮样式等。而在JavaScript代码中,我们为树形节点添加了展开、收起、选中等按钮,增强了树形组件的交互体验。

树形组件的应用

实现好了树形组件,我们可以将其应用到多个场景中,比如商品分类、组织架构、地区选择等。在下面的示例中,我将演示如何使用树形组件来实现一个按地区选择的功能。

首先,我准备了一个包含省、市、区三级的地区数据。然后,我使用上面的树形组件,将地区数据转换成了树形结构,并添加了省市区三个级别的区分和选中情况的状态。

let data = [
  { code: '100000', name: '全国', type: 'COUNTRY', parentId: null },
  { code: '110000', name: '北京市', type: 'PROVINCE', parentId: '100000' },
  { code: '110100', name: '北京市', type: 'CITY', parentId: '110000' },
  { code: '110101', name: '东城区', type: 'DISTRICT', parentId: '110100' },
  { code: '110102', name: '西城区', type: 'DISTRICT', parentId: '110100' },
  // ... 其他省市区数据
];

function buildTree(data, parent) {
  let ul = document.createElement('ul');
  parent.appendChild(ul);
  ul.classList.add('tree');

  data.forEach(function(node) {
    if (node.parentId === parent.dataset.id) {
      let li = document.createElement('li');
      let title = document.createElement('div');
      title.innerText = node.name;
      title.classList.add('title');

      let btnExpand = document.createElement('span');
      btnExpand.innerText = '+';
      btnExpand.classList.add('btn', 'expand');
      btnExpand.onclick = function(event) {
        event.stopPropagation();
        li.classList.toggle('expand');
      };
      title.appendChild(btnExpand);

      let btnSelect = document.createElement('span');
      btnSelect.innerText = '√';
      btnSelect.classList.add('btn', 'select');
      btnSelect.onclick = function(event) {
        event.stopPropagation();
        li.classList.toggle('selected');
        // 处理选中状态
        let code = li.dataset.code;
        let name = li.dataset.name;
        let type = li.dataset.type;
        let checked = li.classList.contains('selected');
        updateSelected(code, name, type, checked);
      };
      title.appendChild(btnSelect);

      li.appendChild(title);
      ul.appendChild(li);
      li.dataset.id = node.code;
      li.dataset.code = node.code;
      li.dataset.name = node.name;
      li.dataset.type = node.type;

      if (node.type === 'CITY') {
        li.classList.add('city');
      } else if (node.type === 'DISTRICT') {
        li.classList.add('district');
      }

      buildTree(data, li);
    }
  });
}

let root = document.getElementById('root');
buildTree(data, root);

// 更新选中状态
function updateSelected(code, name, type, checked) {
  console.log(`选择了 ${name}(${code}),${type},${checked}`);
}

最后的效果是一个可以实现按地区选择的树形组件,用户可以通过展开、收起、选中节点来完成地区选择操作。

示例代码可以参考以下链接:https://codepen.io/xiaolinzi/pen/zYNWAjr

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript树形组件实现无限级树形结构 - Python技术站

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

相关文章

  • 详解Nodejs基于mongoose模块的增删改查的操作

    当我们使用 Node.js 构建应用程序时,我们通常需要连接数据库操作数据。Mongoose 是一个在 Node.js 中操作 MongoDB 数据库的 ODM(对象文档映射器)模块,它使得我们可以更加方便地进行数据存储与操作。 本文将详细讲解如何使用 Mongoose 模块进行增删改查的操作,主要包括以下内容: 连接 MongoDB 数据库 定义模型(Sc…

    node js 2023年6月8日
    00
  • TypeScript保姆级基础教程

    TypeScript保姆级基础教程攻略 1. 了解基础语法 TypeScript是JavaScript的超集,兼容JavaScript的所有语法。因此,首先要熟悉JavaScript的基础语法,包括变量、函数、循环、条件判断等内容。进一步了解TypeScript的静态类型定义、泛型和ES6语法等特性。 示例: 基本变量声明 let str: string =…

    node js 2023年6月8日
    00
  • 基于JavaScript的操作系统你听说过吗?

    当谈到JavaScript的应用时,大多数人会想到网页交互和动态效果,却很少会想到操作系统。然而,这并不意味着JavaScript无法实现操作系统的功能。 什么是基于JavaScript的操作系统? 基于JavaScript的操作系统是使用JavaScript编写的操作系统。它运行在Web浏览器环境中,与传统操作系统不同,它不需要安装或下载,也不需要硬盘或驱…

    node js 2023年6月8日
    00
  • node 版本切换的实现

    关于“node 版本切换的实现”的完整攻略,我将从以下几个方面来讲解: Node 版本管理器介绍 使用 nvm 安装和切换 Node 版本的步骤 使用 n 模块安装和切换 Node 版本的步骤 示例说明:通过 nvm 安装和切换 Node 版本 示例说明:通过 n 模块安装和切换 Node 版本 1. Node 版本管理器介绍 Node 版本管理器是一种用于…

    node js 2023年6月8日
    00
  • Node.js中出现未捕获异常的处理方法

    当在Node.js环境中发生未捕获的异常时,我们可以采用以下方法进行处理。 1. process 对象的 ‘uncaughtException’ 事件 当Node.js应用程序中发生未捕获的异常时,如果没有对其进行处理,应用程序将会崩溃。我们可以通过对 process 对象的 ‘uncaughtException’ 事件进行监听来处理这种异常情况。代码如下:…

    node js 2023年6月8日
    00
  • 详解Node.js一行命令上传本地文件到服务器

    详解Node.js一行命令上传本地文件到服务器的完整攻略如下: 前言 Node.js是一种基于Chrome V8引擎运行的JavaScript运行环境,可以直接在服务器端运行JavaScript代码。Node.js具有非阻塞IO和高并发等优势,因此可以用来处理网络应用程序中的大量并发请求。在此基础上,我们可以轻松地使用Node.js来实现文件上传功能。 依赖…

    node js 2023年6月8日
    00
  • nodejs中操作mysql数据库示例

    下面是关于“nodejs中操作mysql数据库示例”的完整攻略。 1. 安装相关模块 首先,我们需要通过npm来安装以下两个模块: npm install mysql npm install dotenv 其中,mysql是操作mysql数据库的模块,而dotenv是加载环境变量的模块。在本示例中,我们会将连接数据库的参数存储在环境变量中。 2. 连接数据库…

    node js 2023年6月8日
    00
  • JavaScript实现树结构转换的五种方法总结

    当需要将树形结构进行转换时,可以采用JavaScript进行处理。下面介绍JavaScript实现树结构转换的五种方法总结。 方法一:递归法 递归法是常用的处理树形结构的方式。将树形结构节点递归展开,然后通过JS数组的push方法进行数据填充。 function treeArray(tree) { var arr = []; tree.forEach(fun…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部