树形操纵-树形拖拽挑选_玖富娱乐主管发布


玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。

树形操纵数据,做个整顿总结。本篇是关于树节点拖拽挑选,从新天生一棵新树,并支撑删除节点。demo 是基于 jquery 及 easy-ui 库完成的。

媒介:

  • demo 预览
  • 完成功用点:
    • 树形展现、挑选
    • 左边节点支撑拖拽到右边,而且重组为树形展现
    • 右边已选树形节点支撑删除,并统计挑选的子节点个数
    • 支撑默许有子节点数据
  • 截图:

详细完成-loading:

应用 css3 完成。重要运用了 :before:after 挑选器‘画’了两个圆,然后应用border举行圆的调解,末了应用animationtransform:rotate()完成扭转动画。

html:

<div class="loading"></div>

css:

    .loading {
        height: 100%;
        line-height: 100%;
        position: relative;
    }
    .loading:before {
        position: absolute;
        top: calc(50% - 30px);
        left: calc(50% - 30px);
        content: "";
        width: 60px;
        height: 60px;
        border-radius: 100%;
        border: 5px solid skyblue;
        border-left-color: transparent;
        border-right-color: transparent;
        animation: loading 1s linear infinite; 
    }
    .loading:after {
        position: absolute;
        top: calc(50% - 30px);
        left: calc(50% - 30px);
        content: "";
        width: 60px;
        height: 60px;
        border-radius: 100%;
        border: 5px solid yellow;
        border-top-color: transparent;
        border-bottom-color: transparent;
        animation: loading 2s linear infinite; 
    }
    @keyframes loading {
        from {
            transform: rotate(0deg);
        }
        to {
            transform: rotate(360deg);
        }
    }

详细完成-树形挑选:

重要 html 构造以下,css 就不展现,对照简单。

<div class="tree-select">
    <div class="tree-left">
        <div class="search tree-header" id="search">
            <input class="search-input" placeholder="搜刮标签" value="" />
        </div>
        <ul class="tree-con loading" id="tree_select"></ul>
    </div>
    <div class='tree-right'>
        <div class="tip-wrap tree-header">
            <span class="tip-num">已选标签(<span class="num" id="tree_selected_num">0</span>)</span>
            <span class="clear-all" id="tree_selected_clear">清空</span>
        </div>
        <ul class="tree-con" id="tree_selected">
        </ul>
    </div>
</div>

js 代码对照多,先放个 js 代码构造构造图:

-玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。-

个中 event 中完成的是挑选和清空功用。

1. 数据猎取,并衬着左边树:renderSelectTree

treeSelectMod.$treeTarget.addClass('loading');

setTimeout(function () { // 现实中,经由过程 ajax 猎取数据,这儿用 延时 模仿
    treeSelectMod.$treeTarget.removeClass('loading');

    if (result && result.flag && result.data && result.data.length) {
        //实例化树形菜单
        treeSelectMod.$treeTarget.tree({
            data: result.data,
            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) {
                // 折叠树
                treeSelectMod.$treeTarget.tree('collapseAll');
                
                // 节点上制止安排
                $.each($('#tree_select .tree-node'), function(i, item) {
                    $(item).droppable("disable");
                });
            }
        });
        treeSelectMod.setDragAndDrop();

        // 编纂回填:须要有已选数据
        if (isEdit) {
            treeSelectMod.editInit(result.data);
        }
    } else {
        treeSelectMod.$treeTarget.html(treeSelectMod.noDataHtml);
    }
}, 1000);

2. 拖拽操纵:setDragAndDrop

// 设置被拖元素
$("#tree_select .tree-node").draggable({
    proxy: 'clone',
    revert: true, // 拖动完毕后节点将返回它的最先地位
    cursor: 'pointer',
    onStartDrag: function() {
        $(this).draggable('proxy').css({ 'background': '#fff', 'opacity': '0.5' });
    },
    onStopDrag: function(e) {
        // 拖拽置放地位,不是目的不举行操纵
        if (e.target.id != 'tree_selected') {
            return true
        }
        var node = treeSelectMod.$treeTarget.tree('getNode', e.data.target); // 猎取被拖动的节点数据

        // 过滤
        var selectedData = treeSelectMod.selectedData;
        if (node.children && node.children.length) {
            // 被拖拽节点是父节点:推断选中数据中是不是有以后节点,没有,就到场,有就替代(包管子节点都准确)
            var parentNode = {
                id: node.id,
                text: node.text,
                children: [],
                state: node.state || 'closed'
            };
            node.children.forEach(function(item) {
                parentNode['children'].push({
                    id: item.id,
                    text: item.text
                });
            })
            var hasSameParentNode = false;
            for (var i = 0; i < selectedData.length; i  ) {
                if (selectedData[i].id == node.id) {
                    hasSameParentNode = true;
                    selectedData[i] = parentNode;
                    break;
                }
            }
            if (!hasSameParentNode) {
                selectedData.push(parentNode);
            }
        } else {
            // 被拖拽节点为子节点:须要子节点带着其父节点,便于数据准确
            // 经由过程被拖拽节点找其父节点,在选中的数据中举行同级对照,先找到相称的父节点,再在选中的子节点中推断是不是有以后拖拽节点,没有就到场子节点,有不举行操纵。若是连父节点都没有相称的,就连父节点一同到场
            var parent = treeSelectMod.$treeTarget.tree('getParent', e.data.target);
            var childNode = {
                id: node.id,
                text: node.text
            };
            if (parent) {
                var parentNode = {
                    id: parent.id,
                    text: parent.text,
                    state: parent.state || 'closed'
                };
                parentNode['children'] = [];
                parentNode['children'].push(childNode);
                
                var hasSameParentNode = false;
                for (var i = 0; i < selectedData.length; i  ) {
                    if (selectedData[i].id == parent.id) {
                        hasSameParentNode = true;
                        var children = selectedData[i]['children'] || [];
                        var arr = children.filter(function(item) {
                            return item.id == node.id;
                        });
                        if (!arr.length) { // 不存在,到场子节点
                            children.push(childNode);
                        }
                        break;
                    }
                }
                if (!hasSameParentNode) { // 没有相称父节点,连父节点一同到场
                    selectedData.push(parentNode);
                }
            }
        }
        
        // 末了,衬着 DOM
        treeSelectMod.renderSelectedTree(treeSelectMod.selectedData);
    }
});

//设置目的工具许可安排被拖元素
$("#tree_selected").droppable();

3. 衬着已挑选树,及树节点删除:renderSelectedTree

$('#tree_selected').tree({
    data: treeData,
    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>';
        }
        text  = '<span class="tree-node-del">x</span>';
        return text;
    },
    onClick: function(node) {
        // 删除节点
        var selectedData = treeSelectMod.selectedData;
        if (node.children && node.children.length) {
            // 删除节点是父节点:从已挑选的中找到删除节点,举行删除
            for (var i = 0; i < selectedData.length; i  ) {
                if (selectedData[i].id == node.id) {
                    selectedData.splice(i, 1);
                }
            }
        } else {
            // 删除节点是子节点:从已挑选的子级中找到删除子节点,举行删除,并睁开其父节点,轻易检察是不是删除
            for (var i = 0; i < selectedData.length; i  ) {
                for (var j = 0; j < selectedData[i].children.length; j  ) {
                    if (selectedData[i].children[j].id == node.id) {
                        selectedData[i].children.splice(j, 1);
                        selectedData[i].state = 'open';
                    }
                }
                if (!selectedData[i].children.length) { // 末了推断,若是父节点下没有子节点了,就把父节点删除
                    selectedData.splice(i, 1);
                }
            }
        }
        // 从新依据过滤后的数据举行衬着 DOM
        treeSelectMod.renderSelectedTree(treeSelectMod.selectedData);
    },
    onLoadSuccess: function() {
        // 统计挑选的标签:子节点介入统计
        $('#tree_selected_num').html(treeSelectMod.getTreeChildNum(treeSelectMod.selectedData));
    }
});

其他操纵对照简单,就不赘述了,详细完成可看demo。

完成效果,只需每次右边节点拖拽安排了和右边节点举行了节点删除波折,左边 DOM 就要举行一遍衬着。可能会存在机能题目,但现在没更好的完成计划。(迎接有更好计划的供应发起,~~)

末了就是,现在完成的计划,只支撑二级树构造,多级是不支撑的。

-玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。