You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 13:54:07