<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
list-style: none;
}
.zsw-org {
display: table;
margin: 0 auto;
}
.zsw-org li {
display: table-cell;
text-align: center;
}
.zsw-cc {
padding: 0 10px;
text-align: center;
}
.zsw-cc>div {
display: inline-block;
border: 1px solid #990000;
height: 35px;
line-height: 35px;
padding: 0 10px;
border-radius: 3px;
white-space: nowrap;
cursor: default;
position: relative;
}
.zsw-cc>div:hover>.child-hide {
display: block !important;
}
.child-hide {
position: absolute;
bottom: -10px;
display: none;
height: 15px;
line-height: 15px;
100%;
left: 0;
text-align: center;
}
.zsw-vertical {
text-align: left;
}
.zsw-vertical div {
display: inline-block;
50%;
border-right: 1px solid #990000;
height: 15px;
}
.zsw-org-tree {
margin-top: -6px;
}
.zsw-org-tree>li .zsw-line>span {
height: 15px;
display: inline-block;
100%;
border-top: #990000 1px solid;
text-align: left;
}
.zsw-org-tree>li .zsw-line>span>span {
50%;
border-right: #990000 1px solid;
display: block;
height: 15px;
}
.zsw-org-tree>li:first-child {
text-align: right;
}
.zsw-org-tree>li:first-child>.zsw-content>.zsw-line>span {
50%;
border-left: #990000 1px solid;
}
.zsw-org-tree>li:first-child>.zsw-content>.zsw-line>span>span,
.zsw-org-tree>li:last-child>.zsw-content>.zsw-line>span>span {
border: none;
}
.zsw-org-tree>li:last-child {
text-align: left;
}
.zsw-org-tree>li:last-child>.zsw-content>.zsw-line>span {
50%;
border-right: #990000 1px solid;
}
.zsw-line-sign>span {
border-left: none !important;
border-top: none !important;
}
.zsw-org-tree-active{
background-color: cadetblue;
color: #fff;
}
</style>
</head>
<body id="orgTree">
<!-- <ul class="zsw-org">
<li>
<div class="zsw-content">
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
<div class="zsw-vertical">
<div></div>
</div>
<ul class="zsw-org-tree">
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
<div class="zsw-vertical">
<div></div>
</div>
<ul class="zsw-org-tree">
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
</li>
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
</li>
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
</li>
</ul>
</li>
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
</li>
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
<div class="zsw-vertical">
<div></div>
</div>
<ul class="zsw-org-tree">
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
</li>
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
</li>
<li>
<div class="zsw-content">
<div class="zsw-line">
<span>
<span></span>
</span>
</div>
<div class="zsw-cc">
<div>内容</div>
</div>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul> -->
</body>
</html>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
function orgTree(opt) {
//默认参数
this._defOpt = {
//data: undefined,
el: "#orgTree",
//afterContent: undefined,
//afterContentEvent: undefined,
dicNameSet: {
"name": "name",
"child": "child"
},
//contentClick: undefined,
isFlex: false
};
let _opt = $.extend({}, this._defOpt, opt);
//处理html
function joinHtml() {
//第一个节点与后续节点有区别
if (_opt.data) {
//根目录
let _$html = $('<ul class="zsw-org"></ul>');
//第一个节点
let _$li = $('<li></li>')
//第一个节点内容
let _content = '';
_content += '<div class="zsw-content">';
_content += '<div class="zsw-cc">';
_content += '<div>' + _opt.data[_opt.dicNameSet.name] + '</div>';
_content += '</div>';
_content += '</div>';
let _$content = $(_content);
addCustomNode(_$content, null, _opt.data);
_$li.append(_$content);
_$html.append(_$li)
$(_opt.el).html(_$html);
bindContentClick(_$li, _opt.data);
if (_opt.data[_opt.dicNameSet.child]) {
joinHtmlChild(_opt.data[_opt.dicNameSet.child], _$li);
}
}
}
function joinHtmlChild(obj, el) {
if (obj !== null && obj.length > 0) {
//竖线
let verHtml = '';
verHtml += '<div class="zsw-vertical">';
verHtml += '<div></div>';
verHtml += '</div>';
verHtml = $(verHtml);
el.append(verHtml);
//添加子级
let ul = $('<ul class="zsw-org-tree"></ul>');
el.append(ul);
$.each(obj, function (i, item) {
let li = $("<li></li>")
ul.append(li);
let content = '';
content += '<div class="zsw-content">';
if (obj.length > 1) {
content += '<div class="zsw-line">';
}
else {
content += '<div class="zsw-line zsw-line-sign">';
}
content += '<span>';
content += '<span></span>';
content += '</span>';
content += '</div>';
content += '<div class="zsw-cc">';
content += '<div>' + item[_opt.dicNameSet.name] + '</div>';
content += '</div>';
content += '</div>';
content = $(content);
addCustomNode(content, obj, item);
li.append(content);
bindContentClick(li, item);
if (item[_opt.dicNameSet.child]) {
joinHtmlChild(item[_opt.dicNameSet.child], li)
}
})
}
}
function addCustomNode(el, parentData, data) {
if (_opt.afterContent !== undefined && _opt.afterContent !== '') {
let afterConten = $(_opt.afterContent)
el.find(".zsw-cc div").append(afterConten);
if (typeof _opt.afterContentEvent === 'function') {
_opt.afterContentEvent(afterConten, el, parentData, data)
}
}
}
//绑定内容点击事件
function bindContentClick(el, data) {
$(el).on("click", ".zsw-cc div", function (e) {
if (_opt.isFlex) {
let ver = $(el).children(".zsw-vertical");
let org = $(el).children(".zsw-org-tree");
if (ver.css("display") === 'block') {
ver.hide();
org.hide();
$(this).append("<span class='child-hide'>V</span>")
}
else {
ver.show();
org.show();
$(this).children(".child-hide").remove()
}
}
$(".zsw-org-tree-active").removeClass('zsw-org-tree-active');
$(el).children(".zsw-content").find(".zsw-cc div").addClass('zsw-org-tree-active')
if (typeof _opt.contentClick === 'function') {
_opt.contentClick(e, data);
}
//阻止冒泡
return false;
})
}
function removeAaary(_arr, _obj) {
var length = _arr.length;
for (var i = 0; i < length; i++) {
if (_arr[i] == _obj) {
if (i == 0) {
_arr.shift(); //删除并返回数组的第一个元素
return _arr;
}
else if (i == length - 1) {
_arr.pop(); //删除并返回数组的最后一个元素
return _arr;
}
else {
_arr.splice(i, 1); //删除下标为i的元素
return _arr;
}
}
}
}
//初始化
joinHtml();
return {
//刷新结构
refresh: function () {
alert(111)
joinHtml();
},
//添加数据
addNode: function (el, pdata, data) {
//alert("未实现");
//addChildNode();
let ul = "";
if (pdata.child != null && pdata.child != undefined && pdata.child) {
pdata.child.push(data);
ul = $(el).siblings("ul")
}
else {
pdata.child = [];
pdata.child.push(data);
ul = $('<ul class="zsw-org-tree"></ul>')
let verHtml = '';
verHtml += '<div class="zsw-vertical">';
verHtml += '<div></div>';
verHtml += '</div>';
verHtml = $(verHtml);
el.parent().append(verHtml)
el.parent().append(ul)
}
let li = '';
li += '<li>';
li += '<div class="zsw-content">';
if (pdata.child.length > 1) {
li += '<div class="zsw-line">';
//修改样式,只允许修改直接下级
ul.children("li").children(".zsw-content").find(".zsw-line-sign").removeClass('zsw-line-sign');
}
else {
li += '<div class="zsw-line zsw-line-sign">';
}
//li += '<div class="zsw-line">';
li += '<span>';
li += '<span></span>';
li += '</span>';
li += '</div>';
li += '<div class="zsw-cc">';
li += '<div>' + data[_opt.dataSet.name] + '</div>';
li += '</div></div>';
li += '</li>';
li = $(li);
ul.append(li);
let _$content = li.find(".zsw-content")
addCustomNode(_$content, data);
bindContentClick(li, data);
},
//删除数据
delNode: function (el, pData, data) {
//alert("未实现")
//delete data;
if (pData == null) {
//顶级节点
_opt.data = null;
$(_opt.el).html("")
}
else {
removeAaary(pData, data);
if(pData.length > 0){
if(pData.length == 1){
let li = el.parent();
li.siblings().children(".zsw-content").find(".zsw-line").addClass("zsw-line-sign");
li.remove();
}
}
else{
let ul = el.parent().parent();
ul.siblings(".zsw-vertical").remove();
ul.remove();
}
}
console.log(_opt.data);
},
//更新数据
uptNode: function (el, contentNode, nData) {
//alert("未实现")
let nodeData = $.extend(contentNode, nData);
let content = el.find('.zsw-cc div');
content.html(nodeData[_opt.dicNameSet.name]);
},
//重置数据
resetData: function (data) {
_opt.data = data;
joinHtml();
}
};
}
//使用示例
var orgTree = new orgTree({
//数据
data: {
name: "名称1",
child: [
{
name: "名称2",
child: [
{
name: "名称2"
},
{
name: "名称3"
}
]
},
{
name: "名称3",
child: [
{
name: "名称2"
}
]
}
]
},
//容器
//el: "#orgTree",
//在名称后面增加的自定义内容
afterContent: "<span>∷</span>",
//自定义内容的函数,将自定义内容的jquery对象以及当前级别的数据抛出,方便自定义事件
afterContentEvent: function (custormNode, contentNode, childNodes, node) {
/*
* custormNode:当前节点中自定义的节点jquery对象 说不定什么时候就能用到
* contentNode:当前节点jquery对象 增删改都需要
* node:当前节点数据,包含子节点 曾删改都需要
* childNodes:当前节点的父节点的子节点集合 删除数据需要,因为数据需要从此集合删除
*/
$(custormNode).on("click", function () {
// console.log("custorm:")
// console.log(node);
// console.log(parentNodeData);
//新节点或者更新后的节点
// var nData = {
// name: "我是新的"
// }
//添加数据
//orgTree.addNode(contentNode, node, nData);
//修改数据
//orgTree.uptNode(contentNode, node, nData);
//删除数据
//orgTree.delNode(contentNode, childNodes, node);
//此处冒泡到内容节点时,注释 return false即可
return false;
})
//addChildNode()
},
//data中的key设置,以下是默认设置
// dataSet: {
// "name": "name",
// "child": "child"
// },
//是否可以隐藏
isFlex: true,
//节点点击方法
contentClick: function (e, data) {
/*
* e:jquery event对象
* data:当前节点数据,包含子节点
*/
console.log("node:")
console.log(data);
}
})
</script>
哎,我这个审美啊