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

yizhihongxing

以下是“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日

相关文章

  • Node.js文件系统fs扩展fs-extra说明

    Node.js 是一个非常流行的 JavaScript 运行环境,它提供了多种操作文件系统的方式。但是,官方的文件系统模块(fs)并不够完善,可能需要使用 fs-extra 这个第三方扩展库。fs-extra 模块为 Node.js 应用程序提供了更好的文件处理方法和 API。 什么是 fs-extra fs-extra 是一个基于 Node.js 文件系统…

    node js 2023年6月8日
    00
  • nodejs爬虫遇到的乱码问题汇总

    Node.js爬虫遇到的乱码问题汇总 近些年来,Node.js的用户数量急剧增长,因为它可以作为一个强大的后端服务器,但它还可以从网站上抓取数据以及爬取网站。然而,在使用Node.js进行爬取操作时,遇到的最常见问题之一是乱码问题。本文将对Node.js爬虫遇到的乱码问题进行总结,并给出解决方案。 1. 编码格式不同 乱码问题的主要原因之一是编码格式不同。网…

    node js 2023年6月8日
    00
  • 利用express启动一个server服务的方法

    启动一个server服务通常需要以下步骤: 使用npm安装express包 npm install express –save 编写一个js文件,使用require引入express const express = require(‘express’); const app = express(); 在app对象上配置路由 app.get(‘/’, (re…

    node js 2023年6月8日
    00
  • 简述pm2常用命令集合及配置文件说明

    下面我给你详细讲解“简述PM2常用命令集合及配置文件说明”的完整攻略。 一、PM2常用命令集合 在使用PM2时,经常需要用到一些常用命令,以下是一些常见命令: 1. pm2 start 启动一个进程启动文件。示例: pm2 start index.js 2. pm2 list 显示所有已经启动的进程列表,示例: pm2 list 3. pm2 restart…

    node js 2023年6月8日
    00
  • Node.js的非阻塞I/O、异步与事件驱动介绍

    Node.js的非阻塞I/O、异步与事件驱动介绍 Node.js是一个基于Chrome V8引擎的非阻塞I/O、事件驱动的轻量级JavaScript运行环境。Node.js的最大特点是使用了非阻塞I/O、异步和事件驱动模型,这种模式可以让Node.js进行高效的I/O操作。在本文中,我们将会详细介绍Node.js的非阻塞I/O、异步和事件驱动模型。 非阻塞I…

    node js 2023年6月8日
    00
  • React Native 的动态列表方案探索详解

    下面我将分享一份对于“React Native 的动态列表方案探索详解”的完整攻略。 React Native 的动态列表方案探索详解 背景 在 React Native 的开发中,动态列表是非常常见的场景。例如商品列表、新闻列表、推荐列表等等。本文将介绍一些常见的动态列表实现方案,并针对每种方案的优缺点进行说明。 方案一:使用 FlatList FlatL…

    node js 2023年6月8日
    00
  • 详解JWT与Token的应用与原理

    详解JWT与Token的应用与原理 什么是JWT JWT(JSON Web Token)是一种用于网络通信的协议,主要用来在网络应用之间传递认证及授权数据。JWT 将用户信息进行编码,形成一个字符串并将其发送到客户端,在客户端需要访问受保护的资源时,将其发送回服务器进行验证。JWT 是有状态的,因为其中包含了用户的信息,而服务器在解析 Token 时,会将其…

    node js 2023年6月8日
    00
  • Node.js的进程管理的深入理解

    Node.js 进程管理是 Node.js 一个重要的功能,可以帮助我们更好地管理和控制 Node.js 运行过程中的进程,提高 Node.js 的稳定性和可靠性。在本文中,我们将深入探讨 Node.js 进程管理的相关内容,包括进程的创建、运行、退出,以及一些常用的进程管理方式。 进程的创建 在 Node.js 中,我们可以通过调用 child_proce…

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