如何在自定义jsTree上下文菜单中实现复制粘贴及文件/文件夹创建
jsTree 自定义上下文菜单实现(含创建分类、复制剪切粘贴)
以下是完整的实现代码,基于静态JSON数据构建jsTree,并实现你需要的所有上下文菜单功能:
<div id="jstree"></div> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" /> <script> // 静态JSON数据 const treeData = [ { id: "1", text: "根目录", type: "folder", children: [ { id: "2", text: "文档文件夹", type: "folder", children: [{ id: "3", text: "简历.pdf", type: "file" }] }, { id: "4", text: "图片文件夹", type: "folder", children: [{ id: "5", text: "头像.png", type: "file" }] } ] } ]; // 存储复制/剪切的节点信息 let clipboard = { node: null, action: null // 'copy' 或 'cut' }; $(function() { $('#jstree').jstree({ core: { data: treeData, check_callback: true // 允许修改树结构 }, types: { folder: { icon: "glyphicon glyphicon-folder-open" }, file: { icon: "glyphicon glyphicon-file" } }, contextmenu: { items: function(node) { const defaultItems = $.jstree.defaults.contextmenu.items(); // 自定义创建菜单,拆分文件/文件夹选项 defaultItems.create = { label: "创建", submenu: { create_folder: { label: "文件夹", action: function(data) { const inst = $.jstree.reference(data.reference); inst.create_node(node, { text: "新文件夹", type: "folder" }, "last", function(newNode) { setTimeout(function() { inst.edit(newNode); }, 100); }); } }, create_file: { label: "文件", action: function(data) { const inst = $.jstree.reference(data.reference); inst.create_node(node, { text: "新文件.txt", type: "file" }, "last", function(newNode) { setTimeout(function() { inst.edit(newNode); }, 100); }); } } } }; // 添加编辑子菜单(复制/剪切/粘贴) defaultItems.edit = { label: "编辑", submenu: { copy: { label: "复制", action: function(data) { const inst = $.jstree.reference(data.reference); clipboard.node = node; clipboard.action = 'copy'; } }, cut: { label: "剪切", action: function(data) { const inst = $.jstree.reference(data.reference); clipboard.node = node; clipboard.action = 'cut'; } }, paste: { label: "粘贴", action: function(data) { const inst = $.jstree.reference(data.reference); if (!clipboard.node || clipboard.node.id === node.id) return; // 仅允许粘贴到文件夹节点 if (node.type !== 'folder') return; if (clipboard.action === 'copy') { // 复制节点:深拷贝原节点数据,避免ID冲突 const copiedNode = JSON.parse(JSON.stringify(clipboard.node)); copiedNode.id = 'copy_' + Date.now(); // 生成新ID inst.create_node(node, copiedNode, "last"); } else if (clipboard.action === 'cut') { // 剪切节点:移动后清空剪贴板 inst.move_node(clipboard.node, node, "last"); clipboard = { node: null, action: null }; } }, // 仅当剪贴板有内容且当前节点是文件夹时显示粘贴选项 disabled: function() { return !clipboard.node || node.type !== 'folder'; } } } }; return defaultItems; } }, plugins: ["contextmenu", "types"] }); }); </script>
关键功能解释
1. 创建菜单的文件/文件夹区分
通过在contextmenu.items中自定义create项,设置submenu拆分出"文件夹"和"文件"两个子选项,分别调用create_node时指定对应的type,同时创建后自动触发编辑状态(inst.edit(newNode)),方便用户直接修改名称。
2. 复制/剪切/粘贴实现
- 剪贴板存储:用全局变量
clipboard记录当前要操作的节点和操作类型(复制/剪切)。 - 复制逻辑:深拷贝原节点数据并生成新ID(避免ID重复冲突),然后调用
create_node添加到目标文件夹下。 - 剪切逻辑:调用
jsTree的move_node方法将原节点移动到目标位置,完成后清空剪贴板。 - 粘贴权限控制:通过
disabled属性控制粘贴按钮的可用性,仅当剪贴板有内容且目标节点是文件夹时才启用。
3. 基础功能(重命名/删除)
保留了jsTree默认上下文菜单中的重命名和删除功能,这些功能依赖check_callback: true配置,允许修改树结构。
内容的提问来源于stack exchange,提问作者Arup Ranjan Sahoo
相关产品推荐
相关产品推荐

