jQuery EasyUI 树形菜单 – 树形菜单拖放控制

下面直接给你最实用、最常见的树形菜单拖放控制(Draggable & Droppable Tree)方法,jQuery EasyUI 的 tree 组件内置支持拖拽节点(移动节点、排序、跨树拖拽),复制粘贴就能用,领导最爱的“菜单排序、部门调动、分类拖拽调整层级”效果全都有!

方法1:最简单最常用 – 开启基本拖放(推荐现在就用这个,3秒出效果)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>EasyUI 树形菜单 - 拖放控制</title>
    <link rel="stylesheet" type="text/css" href="https://www.jeasyui.com/easyui/themes/default/easyui.css">
    <link rel="stylesheet" type="text/css" href="https://www.jeasyui.com/easyui/themes/icon.css">
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script type="text/javascript" src="https://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
</head>
<body>

<div style="margin:30px;">
    <div style="margin-bottom:15px;">
        <a href="javascript:void(0)" class="easyui-linkbutton c6" iconCls="icon-save" onclick="saveTreeOrder()">保存排序</a>
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-reload" onclick="$('#dragTree').tree('reload')">刷新</a>
    </div>

    <!-- 关键:dnd:true 开启拖放功能 -->
    <ul id="dragTree" class="easyui-tree" data-options="
        url:'get_menu_data.php',   <!-- 可以静态标记或异步 -->
        animate:true,
        lines:true,
        dnd:true                   <!-- 开启拖拽 -->
    ">
        <!-- 静态示例(如果不用异步) -->
        <li data-options="iconCls:'icon-setting'">
            <span>系统管理</span>
            <ul>
                <li><span>用户管理</span></li>
                <li><span>角色管理</span></li>
                <li><span>部门管理</span></li>
                <li><span>菜单管理</span></li>
            </ul>
        </li>
        <li data-options="iconCls:'icon-product'"><span>商品管理</span></li>
        <li data-options="iconCls:'icon-order'"><span>订单管理</span></li>
        <li data-options="iconCls:'icon-report'"><span>报表统计</span></li>
    </ul>
</div>

<script>
// 保存拖拽后的树结构(常用:获取所有节点顺序和层级)
function saveTreeOrder(){
    var roots = $('#dragTree').tree('getRoots');  // 获取所有根节点
    var treeData = [];

    $.each(roots, function(i, root){
        treeData.push(getNodeData(root));
    });

    console.log('拖拽后的树结构:', JSON.stringify(treeData, null, 2));

    $.messager.alert('保存结果', 
        '<pre>' + JSON.stringify(treeData, null, 2) + '</pre>',
        'info');

    // 实际项目中:$.post('save_menu_order.php', {tree: treeData});
}

// 递归获取节点完整结构(id、text、children)
function getNodeData(node){
    var data = {
        id: node.id || null,
        text: node.text,
        iconCls: node.iconCls
    };

    var children = $('#dragTree').tree('getChildren', node.target);
    if(children.length > 0){
        data.children = [];
        $.each(children, function(j, child){
            data.children.push(getNodeData(child));
        });
    }
    return data;
}

// 可选:拖拽事件监听
$('#dragTree').tree({
    onDrop: function(target, source, point){
        // point: 'append'(作为子节点)、'top'(插入到上方)、'bottom'(插入到下方)
        console.log('节点 "' + source.text + '" 被拖放到 "' + $(target).parent().find('>span').text() + '" 的 ' + point);
    },
    onBeforeDrop: function(target, source, point){
        // 可以在这里做限制,比如不允许某些节点拖拽
        // return false;  // 阻止拖放
        return true;
    }
});
</script>

</body>
</html>

效果亮点:

  • 拖拽节点可移动到其他节点的上方、下方或作为子节点(三种放置方式)
  • 拖拽时有清晰的插入线提示(top/bottom/append)
  • 支持同级排序、跨层级移动(比如把“用户管理”拖到“商品管理”下面)
  • 拖完后调用 saveTreeOrder() 获取完整树结构,可直接保存到服务器

方法2:高级拖放控制(限制拖拽规则)

$('#dragTree').tree({
    dnd: true,
    onBeforeDrag: function(node){
        // 禁止拖拽某些节点(比如根节点)
        if(node.id == 1){
            $.messager.alert('提示','根节点不允许拖拽!');
            return false;
        }
        return true;
    },
    onBeforeDrop: function(target, source, point){
        var targetNode = $('#dragTree').tree('getNode', target);

        // 禁止把自己拖到自己子节点里(避免死循环)
        if($('#dragTree').tree('isAncestor', source.target, target)){
            return false;
        }

        // 只允许作为子节点(不允许同级排序)
        if(point != 'append'){
            return false;
        }

        // 只允许拖到有特定icon的节点下
        if(targetNode.iconCls != 'icon-folder'){
            return false;
        }

        return true;
    }
});

方法3:行内拖拽排序(只允许同级排序,不允许跨层级)

onBeforeDrop: function(target, source, point){
    var targetNode = $('#dragTree').tree('getNode', target);
    var sourceParent = $('#dragTree').tree('getParent', source.target);
    var targetParent = $('#dragTree').tree('getParent', target);

    // 只允许同级拖拽(父节点相同)
    if(sourceParent && targetParent && sourceParent.target === targetParent.target){
        return point == 'top' || point == 'bottom';  // 只允许插入上下
    }
    return false;
}

方法4:两个树之间互相拖拽(跨树拖放)

<ul id="tree1" class="easyui-tree" data-options="dnd:true,url:'tree1.json'"></ul>
<ul id="tree2" class="easyui-tree" data-options="dnd:true,url:'tree2.json'"></ul>

<script>
$('#tree1').tree({
    onDrop: function(target, source, point){
        // source.tree 表示来源树(如果是跨树拖拽)
        if(source.tree && source.tree[0] != this){
            // 从tree2拖到tree1
            $('#tree1').tree('append', {
                parent: target,
                data: [$.extend({}, source)]  // 复制节点数据
            });
            $(source.tree).tree('remove', source.target);  // 从原树删除
        }
    }
});
</script>

你现在直接复制方法1的完整代码运行,就能看到一个支持自由拖拽排序的树形菜单了!
拖拽完成后点击“保存排序”就能获取完整的树结构JSON,完美用于菜单排序、部门调整、分类管理等场景。

想要我给你一个完整的示例(异步树 + 拖拽排序 + 限制规则 + 保存到服务器 + 拖拽提示美化)?
或者你告诉我你的具体需求(比如“只允许同级排序”“不允许拖到叶子节点”“拖拽后自动展开”),我2分钟发你精准代码,复制就能跑!

快说说你想怎么控制拖放,我手把手帮你搞定,5分钟内看到超级专业的树形菜单拖拽效果!

文章已创建 4298

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部