樹形操作2-或、且關係組合
樹形運算元據整理總結,這篇是第二篇。本篇是關於樹節點拖拽組合,實現或、且的關係,並支援刪除節點。demo 是基於 jquery 及 easy-ui 庫實現的。
截圖:
具體實現-loading:
利用 css3 實現。主要運用了 :before
,:after
選擇器‘畫’了兩個圓點,最後利用animation
及transform:translateX() scale()
實現動畫。利用位移模擬的旋轉,為了使效果更好,加了一點點縮放。
html:
<div class="loading"></div>
css:
.loading { position: relative; height: 100%; line-height: 100%; }.loading:before,.loading:after { position: absolute; top: calc(50% - 5px); left: calc(50% - 5px); content: ""; width: 10px; height: 10px; border-radius: 100%; }.loading:before { background: skyblue; animation: loading-reverse .8s linear infinite; }.loading:after { background: yellow; animation: loading .8s linear infinite; } @keyframes loading { from { transform: translate(-20px) scale(.8); } to { transform: translate(20px) scale(1.1); } } @keyframes loading-reverse { from { transform: translate(20px) scale(.8); } to { transform: translate(-20px) scale(1.1); } }
本想用一個 loading + reverse 實現,但實現效果不是很理想,就用了兩個。下面是一個 loading 的程式碼,可以試一下。
.loading:before { background: skyblue; animation: loading .8s linear infinite reverse; }.loading:after { background: yellow; animation: loading .8s linear infinite; } @keyframes loading { from { transform: translate(-20px) scale(.8); } to { transform: translate(20px) scale(1.1); } }
具體實現:
html 結構比較簡單,左右佈局;左邊是外加了一個 tab 切換及篩選。右側,預設一個清空按鈕。結構如下:
<div class="tree-drag-relation"> <div class="left"> <ul class="nav loading" id="nav"></ul> <div class="search tree-header" id="search"> <input class="search-input" placeholder="搜尋標籤" value="" /> </div> <ul class="tree-con loading" id="tree_drag"></ul> </div> <div class='right'> <div class="relation-header"> <span class="tip-num">已重組節點(<span class="num" id="node_num">0</span>)</span> <span class="clear-all" id="clear_all">清空</span> </div> <div class="relation-con and-wrap" id="relation_con"> </div> </div></div>
為了使 js 程式碼邏輯清晰,結構組織分為了左右 2 部分。左側,負責 tab 切換及樹形資料的展示等,結構如下:
右側負責 或、且 邏輯的處理、刪除、展示及回填等,結構如下:
tab 切換
tab 切換比較簡單,就不上程式碼了。
樹形展示
資料樹形展示,利用的是 easyui 外掛的 tree 外掛,按照官方 API,很容易就能實現。
關鍵點一:要求資料格式為:
[{ id: '', text: '', children: [{}] // 依次類推 }]
關鍵點二:設定支援拖拽,且在載入成功後,設定當前樹節點不可放置被拖拽的節點。具體可看renderDragTree
這個方法。
treeDragMod.$treeTarget.tree({ data: treeData, dnd: true, // 允許拖拽 formatter: function(node) { // 統計子節點個數 var text = '<span class="node-name">' + node.text + '</span>'; if (node.children && node.children.length > 0) { text += '<i class="tip">(' + node.children.length + ')</i>'; } return text; }, onLoadSuccess: function(e, node) { // 摺疊樹 treeDragMod.$treeTarget.tree('collapseAll'); // 節點上禁止放置 $.each($('#tree_drag .tree-node'), function(i, item) { $(item).droppable("disable"); }); } }); relationMod.setDragAndDrop();
關鍵點三:放置,或且的渲染。拖拽實現的另一個點就是放置,因此另一個關鍵點就是設定放置點,並進行放置邏輯處理,這是實現 或、且 關係的重點。具體可看setDragAndDrop
方法實現。
//設定被拖元素$("#tree_drag .tree-node").draggable({ proxy: 'clone', revert: true, //拖動結束後節點將返回它的開始位置 cursor: 'pointer', onStartDrag: function () { $(this).draggable('proxy').css({'background': '#fff', 'opacity': '0.5'}); }, onStopDrag: function (e) { var $target = $(e.target), node = $('#tree_drag').tree('getNode', e.data.target), // 獲取被拖動的節點 $clearAll = $('#clear_all'); // 判斷在可拖拽放置區域,才進行放置操作 if ($target.hasClass('and-wrap') || $target.hasClass('or-wrap')) { $clearAll.show(); $target.append(conHtml()); } function conHtml (relation) { // 處理 and 且的關係 var conHtml = ''; if ($target.hasClass('and-wrap')) { if ($target.children().length) { conHtml += relationMod.andHtml; } var innerHtml = node.children ? relationMod.orConHtml(node.children) : relationMod.orItemHtml(node); conHtml += relationMod.orWrapLeftHtml + innerHtml + '</div>'; } else if ($target.hasClass('or-wrap')) { // 處理 or 或的關係 if ($target.children().length) { conHtml += relationMod.orHtml; } conHtml += node.children ? relationMod.orConHtml(node.children) : relationMod.orItemHtml(node); } return conHtml; } relationMod.setNodeNum(); relationMod.resizeScrollTop(); } });// 設定目標物件允許放置被拖元素$(".and-con, .or-con").droppable();
或、且關係新增時,是透過判斷當前新增節點的元素是否有子元素,有那麼新增元素的時候,就需要新增對應的關係。考慮,新增元素沒有子節點時,是隻需新增節點,而不需要新增關係。
關鍵點四:節點刪除。
假如箭頭為或且
,第一次刪除A
或B
或C
都正確。
採用刪除字母的同時,判斷,上一個箭頭存在,則需要刪除上一個,否則需要刪除下一個箭頭。
刪除 或 item 的如下:
$('body').on('click', '.item-del', function () { // 刪除 item var $this = $(this), $item = $this.closest('.item'), $orWrap = $this.closest('.or-wrap'); // 刪除當前元素及關係 // 上一個存在,刪上一個,否則刪下一個 var $prev = $item.prev('.or'); if ($prev.length) { $prev.remove(); } else { var $next = $item.next('.or'); if ($next.length) { $next.remove(); } } $item.remove(); // 刪除後,若其父元素無子元素,則刪除其父元素 if ($orWrap.children('.item').length == 0) { $orWrap.remove(); } relationMod.setNodeNum(); })
刪除且的邏輯和這個類似。
其他操作比較簡單,就不贅述了,具體實現可看。
最後就是,目前實現的方案,只支援二級樹結構,多級是不支援的。
原文出處:https://www.cnblogs.com/EnSnail/p/10268643.html
作者:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4479/viewspace-2820167/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 樹形或級聯關係
- 樹形結構的處理——組合模式(五)模式
- 樹形結構的處理——組合模式(四)模式
- 樹形結構的處理——組合模式(三)模式
- 樹形結構的處理——組合模式(二)模式
- 樹形結構的處理——組合模式(一)模式
- 物件導向程式設計程式碼詳解(依賴關係,關聯關係,組合關係)物件程式設計
- 機器碼 指令 組合語言 的關係機器碼組合語言
- UML關係(泛化,實現,依賴,關聯(聚合,組合))
- sqlalchemy關係操作SQL
- 溝槽的組合變形
- 關於資料庫操作多個操作組合的處理資料庫
- 為什麼更推薦使用組合而非繼承關係?繼承
- 一分鐘搞懂邏輯運算子&(並且) , |(或者) , !(非) , ^(異或) , &&(短路與) , ||(短路或)之間的關係
- 設計模式系列之組合模式(Composite Pattern)——樹形結構的處理設計模式
- 2- hive後設資料與hadoop的關係HiveHadoop
- 通過遞迴實現,單表父子關係資料 或者上下級關係資料的組合遞迴
- JS 將有父子關係的陣列轉換成樹形結構資料JS陣列
- js將有父子關係的資料轉換成樹形結構資料JS
- java的類之間的關係:泛化、依賴、關聯、實現、聚合、組合Java
- mysql將多行資料合併或按組合並MySql
- “光棍合娶老婆”教授反擊:男女關係就是交易關係
- RxJava操作符之組合操作符(六)RxJava
- 如何快速、且易懂編寫Java遞迴生成樹形選單結構Java遞迴
- 設計模式學習筆記(十三)組合模式及其在樹形結構中的應用設計模式筆記
- 資料的相關性或因果關係 - KDnuggets
- 關於組合模式的疑惑模式
- 樹形DP!
- 樹形DP
- 樹上染色(樹形dp)
- jwt偽造身份組組組合拳艱難通關JWT
- SQLALchemy操作MySQL關係型資料庫MySql資料庫
- mysqlclient操作MySQL關係型資料庫MySqlclient資料庫
- FastAPI(44)- 操作關係型資料庫ASTAPI資料庫
- 關於樹上路徑異或和的思考
- 自組織的鐵三角關係
- js 函式中形參與實參的關係JS函式
- 線段與多邊形關係的演算法演算法