jQuery UI克隆主拖拽元素并实现克隆元素可拖拽的问题
问题描述
页面顶部有两个可拖拽元素X和O,下方是3x3可放置网格。需要实现以下效果:
- 把
X或O克隆到网格单元格,克隆出来的元素也能拖拽到其他单元格 - 每个单元格只能放一个元素
- 元素从单元格移走后,原单元格要恢复成可放置状态
当前代码存在的问题:
- 克隆出来的元素没法拖拽;如果启用
cloned.draggable(),又会出现新问题:- 克隆元素能拖进禁用的单元格或者已经有元素的单元格
- 元素移出后,原单元格会被禁用,无法再放其他元素
解决方案
- 统一拖拽逻辑:不管是顶部的主元素还是克隆出来的元素,都用相同的拖拽配置,并且拖拽时都用
helper: "clone",同时在拖拽开始时记录克隆元素的原单元格。 - 严格放置校验:
- 放置前先检查目标单元格是不是空的、有没有被禁用,不符合条件就不处理
- 区分两种拖拽场景:从顶部拖入时克隆元素;从其他单元格拖入时,把元素移过去并恢复原单元格的可用状态
- 调整禁用时机:只有单元格里有元素时才禁用,元素移走后立刻启用原单元格。
修改后的代码
CSS(无改动)
.header{ padding: 20px; background: #000; color: #fff; text-align: center; } .drag{ background: red; padding: 10px; margin-right: 20px; } .zone{ width: 80%; margin: 40px auto; } .drop{ display: inline-block; width: 27%; border: 1px solid #000; height: 70px; padding: 10px; vertical-align: middle; text-align: center; } .ui-droppable-disabled { background: #494f54; }
HTML(无改动)
<div class="header"> <span class="drag main">X</span> <span class="drag main">O</span> </div> <div class="zone"> <div class="drop"></div> <div class="drop"></div> <div class="drop"></div> <div class="drop disabled"></div> <!-- Droppable Disabled --> <div class="drop"></div> <div class="drop"></div> <div class="drop"></div> <div class="drop"></div> <div class="drop"></div> </div>
jQuery(核心修改)
// 初始化拖拽元素的通用函数 function initDraggable($elem) { $elem.draggable({ helper: "clone", start: function(event, ui) { // 记录克隆元素的原父单元格 $(this).data("originalParent", $(this).parent(".drop")); } }); } // 初始化顶部的主拖拽元素 initDraggable($(".drag.main")); $(".drop").droppable({ accept: ".drag", drop: function(event, ui) { const $targetCell = $(this); // 跳过禁用的单元格或已有元素的单元格 if ($targetCell.hasClass("ui-droppable-disabled") || $targetCell.children(".drag").length > 0) { return; } const $draggedElem = ui.draggable; if ($draggedElem.hasClass("main")) { // 从顶部拖入:克隆元素并添加到目标单元格 const clonedElem = $draggedElem.clone().removeClass("main"); $targetCell.append(clonedElem); initDraggable(clonedElem); } else { // 从其他单元格拖入:移动元素到目标单元格 const $originalCell = $draggedElem.data("originalParent"); $draggedElem.appendTo($targetCell); // 恢复原单元格的可用状态并清空 $originalCell.empty().droppable("enable"); } // 禁用当前目标单元格(已有元素) $targetCell.droppable("disable"); } }); // 初始化禁用指定单元格 $('.disabled').droppable('disable');
内容的提问来源于stack exchange,提问作者mm1234
相关产品推荐
相关产品推荐

