FancyTree DnD如何仅允许拖入有效文件夹 禁止在父级外放置节点
FancyTree 限制仅拖入指定文件夹解决方案
问题根因
现有代码仅校验了拖放命中目标节点本身的droppable属性,未覆盖「拖入两个同级节点之间空隙」的场景:当拖放到空隙位置时,FancyTree的命中模式hitMode为before/after,实际插入位置的父级为当前命中节点的父节点,这部分父级权限没有做校验,所以会出现可以拖入不可放置文件夹下空隙的问题。
实现方案
- 保留原有
dragEnter的校验逻辑,新增dragOver事件处理,覆盖空隙拖放的父级权限校验 - 根据拖放命中模式
hitMode判断实际需要校验的节点:- 当
hitMode为over时,校验当前命中节点的droppable属性 - 当
hitMode为before/after时,校验当前命中节点的父节点的droppable属性
- 当
- 可选在
dragDrop事件中新增二次校验,避免极端场景下的异常放置
完整配置代码
$("#tree").fancytree({ // 其他基础配置省略 extensions: ["dnd"], dnd: { autoExpandMS: 400, focusOnClick: true, preventVoidMoves: true, // 禁止拖到根节点前的空隙,可按需开启 preventRecursiveMoves: true, // 禁止拖到自身子节点下,可按需开启 dragEnter: function(node, data) { // 原有逻辑保留:禁止拖入droppable为false的节点本身 return node.data.droppable !== false; }, dragOver: function(node, data) { // 新增空隙拖放校验逻辑 const hitMode = data.hitMode; let checkNode = hitMode === "over" ? node : node.parent; // 校验节点是否允许放置 return checkNode.data.droppable !== false; }, dragDrop: function(node, data) { // 新增二次校验,确保只有合法位置允许放置 const hitMode = data.hitMode; let parentNode = hitMode === "over" ? node : node.parent; if (parentNode.data.droppable !== true) { return; } // 原有放置逻辑,比如把拖放节点移动到目标位置 data.otherNode.moveTo(parentNode, hitMode); } } });
效果适配
你只需按规则给节点设置droppable属性即可匹配需求:
- 给
Static、Cycles节点的droppable设为false - 给
[0]、[1]、[2]节点的droppable设为true
最终效果:
- 无法直接拖入
Static、Cycles节点本身 - 无法拖入
Cycles下[0]/[1]/[2]之间的空隙 - 仅可以拖入
[0]/[1]/[2]节点内部
内容的提问来源于stack exchange,提问作者Shredderx
相关产品推荐
相关产品推荐

