Nestable2如何禁止子节点拖入其他父节点?求技术解决方案
解决Nestable2子节点仅能在自身父节点内拖拽的问题
你找的方向没错,用beforeDragStop做拖拽验证是正确思路,但问题出在对参数p的处理上——它并不是直接的目标父节点元素,直接取它的data属性自然拿不到有效值。咱们来调整下逻辑:
核心需求很明确:标记为type="field"的子节点,只能在同一个groupid的父节点范围内移动,禁止跨父节点拖拽。
修改后的验证代码
$('#nestable').nestable({ beforeDragStop: function(l, e, p) { // 获取源节点的类型和所属groupid const sourceType = $(e).data('type'); const sourceGroupId = $(e).data('groupid'); // 只对field类型的节点做跨父节点限制,其他类型直接放行 if (sourceType !== 'field') return true; // 关键:找到拖拽目标位置对应的父节点(带data-groupid的那个节点) let targetParent = $(p).closest('[data-groupid]'); // 特殊情况处理:如果拖拽到空父节点的ul下,需要再向上找一层父节点 if (!targetParent.length) { targetParent = $(p).parent().closest('[data-groupid]'); } const destinationGroupId = targetParent.data('groupid'); // 验证源和目标的groupid是否一致,不一致则阻止拖拽完成 return sourceGroupId === destinationGroupId; } });
关键调整说明
- 准确定位目标父节点:通过
closest('[data-groupid]')向上查找最近的带data-groupid属性的节点,确保拿到的是真正的父节点信息,而非插入位置的临时元素。 - 兼容空父节点场景:如果拖拽到一个没有子节点的空父节点下,
p可能直接指向空的ul标签,这时候需要通过parent()再向上追溯父节点。 - 简化逻辑判断:直接返回
sourceGroupId === destinationGroupId的布尔值,符合beforeDragStop的返回规则(false阻止拖拽,true允许)。
配套DOM结构提示
确保你的父节点都正确设置了data-groupid属性,比如:
<div id="nestable"> <ul class="dd-list"> <li class="dd-item" data-groupid="5"> <div class="dd-handle">父节点(group5)</div> <ul class="dd-list"> <li class="dd-item" data-type="field" data-groupid="5"> <div class="dd-handle">子节点1</div> </li> </ul> </li> <li class="dd-item" data-groupid="6"> <div class="dd-handle">父节点(group6)</div> <ul class="dd-list"> <!-- 这里无法拖入group5的子节点 --> </ul> </li> </ul> </div>
这样调整后,就能实现子节点仅在自身父节点内拖拽的需求了。
内容的提问来源于stack exchange,提问作者Nayan Hodar
相关产品推荐
相关产品推荐

