最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用HTML+JavaScript實現(xiàn)具有交互功能的組織架構(gòu)圖

 更新時間:2026年06月06日 08:18:24   作者:bjzhang75  
在開發(fā)大型應用程序時,設計良好的組織架構(gòu)圖對于團隊協(xié)作和代碼維護非常重要,這篇文章主要介紹了使用HTML+JavaScript實現(xiàn)具有交互功能的組織架構(gòu)圖的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

一、組織架構(gòu)圖

在企業(yè)管理系統(tǒng)或團隊協(xié)作平臺中,組織結(jié)構(gòu)圖是一種重要的可視化工具,能夠清晰地展示公司的層級關系和人員分布。本文將詳細介紹如何使用 HTML、CSS 和 JavaScript 從零開始構(gòu)建一個具有交互功能的組織結(jié)構(gòu)圖。

二、效果演示

本項目呈現(xiàn)了一個典型的公司組織架構(gòu),從上級開始逐層向下展示各個部門及員工職位。用戶可以通過點擊節(jié)點上的 +/- 按鈕來展開或收起子節(jié)點,也可以通過頂部的“展開/收起全部”按鈕一鍵控制所有節(jié)點的狀態(tài)。默認情況下,部分節(jié)點被設置為收起狀態(tài)以避免圖表過于龐大,用戶可以根據(jù)需要自由展開查看詳細信息。

三、系統(tǒng)分析

1.頁面結(jié)構(gòu)

系統(tǒng)主要包括以下幾個功能區(qū)域:

1.1 操作區(qū)域

該區(qū)域位于主內(nèi)容上方,提供全局操作按鈕,目前只有一個“展開/收起全部”的功能按鈕,用戶可以一鍵控制所有節(jié)點的展開狀態(tài)。

<div class="actions">
  <button onclick="toggleAll()">展開/收起全部</button>
</div>

1.2 組織結(jié)構(gòu)圖區(qū)域

這是實際渲染組織結(jié)構(gòu)圖的核心區(qū)域,使用 #orgChart 作為根節(jié)點容器。

<div class="org-chart-container">
  <div class="org-chart" id="orgChart"></div>
</div>

2 核心功能實現(xiàn)

2.1 數(shù)據(jù)結(jié)構(gòu)定義

組織結(jié)構(gòu)圖的數(shù)據(jù)源是一個嵌套的 json 數(shù)據(jù),每個節(jié)點包含 id、name、position 和 children 屬性。這種樹形數(shù)據(jù)結(jié)構(gòu)非常適合表示層級關系,并且易于遍歷和渲染。

var orgData = {
  id: 1,
  name: "張偉",
  position: "CEO",
  children: [
    {
      id: 2,
      name: "李娜",
      position: "技術總監(jiān)",
      children: [
        // ... 更多子節(jié)點
      ]
    },
    // ... 更多同級節(jié)點
  ]
};

2.2 節(jié)點渲染邏輯

使用遞歸方式渲染整個組織結(jié)構(gòu)圖,通過遞歸遍歷數(shù)據(jù)結(jié)構(gòu),為每個節(jié)點創(chuàng)建對應的DOM元素,并根據(jù)是否有子節(jié)點添加相應的CSS類名。

function renderOrgChart(data, container) {
  // 創(chuàng)建當前節(jié)點
  var nodeEl = document.createElement('div');
  nodeEl.className = 'node';
  nodeEl.dataset.id = data.id;

  // 如果有子節(jié)點,添加標識類
  if (data.children && data.children.length > 0) {
    nodeEl.classList.add('has-children');
  }

  // 設置節(jié)點內(nèi)容
  nodeEl.innerHTML = `
      <div class="title">${data.name}</div>
      <div class="position">${data.position}</div>
      <div class="toggle-btn"></div>
    `;
  // 為切換按鈕添加點擊事件
  if (data.children && data.children.length > 0) {
    const toggleBtn = nodeEl.querySelector('.toggle-btn');
    toggleBtn.addEventListener('click', function(e) {
      e.stopPropagation();
      nodeEl.classList.toggle('collapsed');
    });
  }

  container.appendChild(nodeEl);

  // 如果有子節(jié)點,創(chuàng)建子節(jié)點容器
  if (data.children && data.children.length > 0) {
    var childrenEl = document.createElement('div');
    childrenEl.className = 'children';

    data.children.forEach((child, index) => {
      var childWrapper = document.createElement('div');
      childWrapper.className = 'child';

      // 添加特殊類名用于樣式控制
      if (data.children.length === 1) {
        childWrapper.classList.add('only-child');
      } else if (index === 0) {
        childWrapper.classList.add('first-child');
      } else if (index === data.children.length - 1) {
        childWrapper.classList.add('last-child');
      }

      renderOrgChart(child, childWrapper);
      childrenEl.appendChild(childWrapper);
    });

    container.appendChild(childrenEl);
  }

  // 默認收起部分節(jié)點
  if (data.id === 2 || data.id === 4) {
    nodeEl.classList.add('collapsed');
  }
}

2.3節(jié)點展開/收起功能

通過給節(jié)點添加/移除 .collapsed 類來控制子節(jié)點的顯示與隱藏。CSS 中利用相鄰兄弟選擇器來隱藏被收起節(jié)點的子級容器;同時,通過偽元素 ::after 在節(jié)點下方顯示 +/- 按鈕,提升用戶體驗。(相關事件在“節(jié)點渲染邏輯”中“為切換按鈕添加點擊事件”綁定)

2.4 全部展開/收起

首先判斷當前是否所有節(jié)點都處于收起狀態(tài),然后統(tǒng)一執(zhí)行相反的操作。

function toggleAll() {
  var nodes = document.querySelectorAll('.node.has-children');
  var isAllCollapsed = Array.from(nodes).every(node => node.classList.contains('collapsed'));

  nodes.forEach(node => {
    if (isAllCollapsed) {
      node.classList.remove('collapsed');
    } else {
      node.classList.add('collapsed');
    }
  });
}

四、擴展建議

  • 節(jié)點編輯功能:支持雙擊節(jié)點進入編輯狀態(tài),修改人員信息
  • 拖拽排序:引入拖拽庫,實現(xiàn)組織架構(gòu)的可視化調(diào)整
  • 導出功能:支持將組織結(jié)構(gòu)圖導出為圖片或PDF格式
  • 主題定制:提供更多顏色方案和樣式選項,滿足不同企業(yè)的品牌形象需求

五、完整代碼

git地址:https://gitee.com/ironpro/hjdemo/blob/master/orgchart/index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>組織結(jié)構(gòu)圖</title>
  <style>
      * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
      }
      body {
          background-color: #f5f5f5;
          min-height: 100vh;
          padding: 20px;
      }
      .container {
          max-width: 980px;
          margin: 0 auto;
          background: white;
          border-radius: 15px;
          box-shadow: 0 20px 40px rgba(0,0,0,0.1);
          overflow: hidden;
      }
      .header {
          background: #45a049;
          color: white;
          padding: 20px;
          text-align: center;
      }
      .header h1 {
          font-size: 24px;
          font-weight: 500;
      }
      .main {
          padding: 20px;
      }
      .org-chart-container {
          display: flex;
          justify-content: center;
          overflow: auto;
          padding: 20px 0;
      }
      .org-chart {
          display: flex;
          flex-direction: column;
          align-items: center;
          position: relative;
      }

      .node {
          background-color: white;
          border: 2px solid #4CAF50;
          border-radius: 8px;
          padding: 15px;
          width: 120px;
          text-align: center;
          box-shadow: 0 2px 5px rgba(0,0,0,0.1);
          position: relative;
          cursor: pointer;
          transition: all 0.3s ease;
          display: inline-block;
      }

      .node:hover {
          box-shadow: 0 4px 10px rgba(0,0,0,0.5);
      }

      .node .title {
          font-weight: bold;
          color: #333;
          margin-bottom: 5px;
      }

      .node .position {
          color: #666;
          font-size: 14px;
      }

      .children {
          display: flex;
          justify-content: center;
          margin-top: 40px;
          position: relative;
      }

      .children::before {
          content: '';
          position: absolute;
          top: -40px;
          left: 50%;
          width: 2px;
          height: 20px;
          background-color: #4CAF50;
      }

      .child {
          position: relative;
          padding: 0 10px;
          text-align: center;
      }

      .child::before {
          content: '';
          position: absolute;
          top: -20px;
          left: 50%;
          width: 2px;
          height: 20px;
          background-color: #4CAF50;
      }

      .child::after {
          content: '';
          position: absolute;
          top: -20px;
          left: 0;
          width: 100%;
          height: 2px;
          background-color: #4CAF50;
      }

      .first-child::after {
          width: 50%;
          left: 50%;
      }

      .last-child::after {
          width: 50%;
      }

      .only-child::after {
          width: 0;
      }

      .actions {
          text-align: center;
      }

      button {
          background-color: #4CAF50;
          color: white;
          border: none;
          padding: 10px 15px;
          border-radius: 4px;
          cursor: pointer;
          margin: 0 5px;
          font-size: 14px;
      }

      button:hover {
          background-color: #45a049;
      }

      .node.collapsed + .children {
          display: none;
      }
      .node .toggle-btn::after {
          content: '-';
          position: absolute;
          bottom: -10px;
          left: 50%;
          transform: translateX(-50%);
          width: 20px;
          height: 20px;
          background-color: #4CAF50;
          color: white;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
          font-weight: bold;
          font-size: 16px;
          z-index: 9;
          cursor: pointer;
      }
      .node.collapsed .toggle-btn::after {
          content: '+';
      }
      .node:not(.has-children) .toggle-btn {
          display: none;
      }
  </style>
</head>
<body>
<div class="container">
  <div class="header">
    <h1>組織結(jié)構(gòu)圖</h1>
  </div>
  <div class="main">
    <div class="actions">
      <button onclick="toggleAll()">展開/收起全部</button>
    </div>
    <div class="org-chart-container">
      <div class="org-chart" id="orgChart"></div>
    </div>
  </div>
</div>
<script>
  var orgData = {
    id: 1,
    name: "張偉",
    position: "CEO",
    children: [
      {
        id: 2,
        name: "李娜",
        position: "技術總監(jiān)",
        children: [
          {
            id: 4,
            name: "王強",
            position: "前端主管",
            children: [
              { id: 7, name: "陳晨", position: "前端工程師" },
              { id: 8, name: "劉芳", position: "UI設計師" }
            ]
          },
          {
            id: 5,
            name: "趙磊",
            position: "后端主管",
            children: [
              { id: 9, name: "孫麗", position: "Java工程師" },
              { id: 10, name: "周鵬", position: "數(shù)據(jù)庫專家" }
            ]
          }
        ]
      },
      {
        id: 3,
        name: "馬華",
        position: "市場總監(jiān)",
        children: [
          {
            id: 6,
            name: "吳敏",
            position: "市場經(jīng)理",
            children: [
              { id: 11, name: "鄭濤", position: "市場專員" },
              { id: 12, name: "黃娟", position: "品牌專員" }
            ]
          }
        ]
      }
    ]
  };

  // 渲染組織結(jié)構(gòu)圖
  function renderOrgChart(data, container) {
    // 創(chuàng)建當前節(jié)點
    var nodeEl = document.createElement('div');
    nodeEl.className = 'node';
    nodeEl.dataset.id = data.id;

    // 如果有子節(jié)點,添加標識類
    if (data.children && data.children.length > 0) {
      nodeEl.classList.add('has-children');
    }

    // 設置節(jié)點內(nèi)容
    nodeEl.innerHTML = `
        <div class="title">${data.name}</div>
        <div class="position">${data.position}</div>
        <div class="toggle-btn"></div>
      `;
    // 為切換按鈕添加點擊事件
    if (data.children && data.children.length > 0) {
      const toggleBtn = nodeEl.querySelector('.toggle-btn');
      toggleBtn.addEventListener('click', function(e) {
        e.stopPropagation();
        nodeEl.classList.toggle('collapsed');
      });
    }

    container.appendChild(nodeEl);

    // 如果有子節(jié)點,創(chuàng)建子節(jié)點容器
    if (data.children && data.children.length > 0) {
      var childrenEl = document.createElement('div');
      childrenEl.className = 'children';

      data.children.forEach((child, index) => {
        var childWrapper = document.createElement('div');
        childWrapper.className = 'child';

        // 添加特殊類名用于樣式控制
        if (data.children.length === 1) {
          childWrapper.classList.add('only-child');
        } else if (index === 0) {
          childWrapper.classList.add('first-child');
        } else if (index === data.children.length - 1) {
          childWrapper.classList.add('last-child');
        }

        renderOrgChart(child, childWrapper);
        childrenEl.appendChild(childWrapper);
      });

      container.appendChild(childrenEl);
    }

    // 默認收起部分節(jié)點
    if (data.id === 2 || data.id === 4) {
      nodeEl.classList.add('collapsed');
    }
  }

  // 初始化組織結(jié)構(gòu)圖
  function initOrgChart() {
    var container = document.getElementById('orgChart');
    container.innerHTML = '';
    renderOrgChart(orgData, container);
  }

  // 展開/收起全部節(jié)點
  function toggleAll() {
    var nodes = document.querySelectorAll('.node.has-children');
    var isAllCollapsed = Array.from(nodes).every(node => node.classList.contains('collapsed'));

    nodes.forEach(node => {
      if (isAllCollapsed) {
        node.classList.remove('collapsed');
      } else {
        node.classList.add('collapsed');
      }
    });
  }

  initOrgChart();
</script>
</body>
</html>

總結(jié)

到此這篇關于使用HTML+JavaScript實現(xiàn)具有交互功能的組織架構(gòu)圖的文章就介紹到這了,更多相關JS組織架構(gòu)圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • javascript獲取指定區(qū)間范圍隨機數(shù)的方法

    javascript獲取指定區(qū)間范圍隨機數(shù)的方法

    下面小編就為大家?guī)硪黄猨avascript獲取指定區(qū)間范圍隨機數(shù)的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 使用Promise封裝小程序wx.request的實現(xiàn)方法

    使用Promise封裝小程序wx.request的實現(xiàn)方法

    這篇文章主要介紹了使用Promise封裝小程序wx.request的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11
  • JavaScript 消息框效果【實現(xiàn)代碼】

    JavaScript 消息框效果【實現(xiàn)代碼】

    下面小編就為大家?guī)硪黄狫avaScript 消息框效果【實現(xiàn)代碼】。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考
    2016-04-04
  • 詳解Webpack + ES6 最新環(huán)境搭建與配置

    詳解Webpack + ES6 最新環(huán)境搭建與配置

    這篇文章主要介紹了詳解Webpack + ES6 最新環(huán)境搭建與配置,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • JS對img進行操作(換圖片/切圖/輪換/停止)

    JS對img進行操作(換圖片/切圖/輪換/停止)

    JS對img進行操作包括:換圖片/切圖/輪換/停止輪換等等,在本文將逐一實現(xiàn),感興趣的朋友可以參考下哈,希望對你學習js知識有所幫助
    2013-04-04
  • Javascript點擊按鈕隨機改變數(shù)字與其顏色

    Javascript點擊按鈕隨機改變數(shù)字與其顏色

    這篇文章主要介紹了Javascript點擊按鈕隨機改變數(shù)字和其字體的顏色,實現(xiàn)后的效果很不錯,具有一定的參考價值,有需要的可以參考借鑒,下面來一起看看。
    2016-09-09
  • 小程序?qū)崿F(xiàn)投票進度條

    小程序?qū)崿F(xiàn)投票進度條

    這篇文章主要為大家詳細介紹了小程序?qū)崿F(xiàn)投票進度條,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • JavaScript中concat復制數(shù)組方法淺析

    JavaScript中concat復制數(shù)組方法淺析

    在本篇文章里小編給大家總結(jié)了關于JavaScript中concat復制數(shù)組方法知識點,有需要的朋友們可以學習下。
    2019-01-01
  • javascript實現(xiàn)緩動動畫效果

    javascript實現(xiàn)緩動動畫效果

    這篇文章主要為大家詳細介紹了javascript實現(xiàn)緩動動畫效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • JS實現(xiàn)點擊復選框變更DIV顯示狀態(tài)的示例代碼

    JS實現(xiàn)點擊復選框變更DIV顯示狀態(tài)的示例代碼

    下面小編就為大家分享一篇JS實現(xiàn)點擊復選框變更DIV顯示狀態(tài)的示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12

最新評論

临沧市| 丽江市| 万宁市| 铁力市| 钦州市| 星座| 大同县| 洞口县| 都兰县| 鸡泽县| 密云县| 昆山市| 兴和县| 井陉县| 阜康市| 吉木萨尔县| 赞皇县| 谢通门县| 唐河县| 松阳县| 徐水县| 白银市| 洛宁县| 阳泉市| 武定县| 衡东县| 游戏| 塔城市| 临桂县| 土默特右旗| 乌审旗| 乐山市| 汉川市| 三都| 襄城县| 吴旗县| 新兴县| 天峻县| 福建省| 延川县| 牙克石市|