SortableJS拖拽问题:无法将元素拖入无子元素的同级节点
问题原因及解决方案
核心问题
- 初始化范围局限:你仅给页面加载时已存在子元素的
ul初始化了Sortable,没有子元素的节点内部无ul容器,Sortable无法绑定到不存在的元素,因此无法接收拖拽项。 - 重复ID违规:HTML中多次使用
id="category-list",ID必须唯一,这会导致选择器匹配异常。
修复步骤
1. 修正HTML结构
- 将重复的
id="category-list"改为类名class="category-list" - 给每个可能作为父节点的
<li>添加空的<ul class="list-group category-list"></ul>容器,确保即使没有子元素也能接收拖拽项
2. 更新JavaScript代码
- 基于类名选择所有需要初始化的
ul元素 - 添加逻辑确保拖拽后目标节点始终有可接收子元素的
ul容器
修改后的完整代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/js/all.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.2/Sortable.min.js"></script> <div class="container" id="handle"> <ul class="list-group category-list"> <li class="list-group-item" data-id="17"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>Home <ul class="list-group category-list"> <li class="list-group-item" data-id="15"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>Test Forum <ul class="list-group category-list"></ul> </li> <li class="list-group-item" data-id="9"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>Hosting Support <ul class="list-group category-list"></ul> </li> <li class="list-group-item" data-id="21"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>Forum <ul class="list-group category-list"></ul> </li> <li class="list-group-item" data-id="10"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP Support <ul class="list-group category-list"> <li class="list-group-item" data-id="18"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP 7 Support <ul class="list-group category-list"> <li class="list-group-item" data-id="20"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>HTAccess <ul class="list-group category-list"></ul> </li> </ul> </li> <li class="list-group-item" data-id="11"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP 8 Support <ul class="list-group category-list"></ul> </li> <li class="list-group-item" data-id="19"> <i class="fa-solid fa-up-down-left-right handle pe-2"></i>MySQL Support <ul class="list-group category-list"></ul> </li> </ul> </li> </ul> </li> </ul> </div>
CSS
@import "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"; @import "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/fontawesome.min.css";
JavaScript
$(document).ready(function() { // 初始化所有category-list下的ul function initSortable() { document.querySelectorAll(".category-list ul").forEach(function(listEl) { if (!listEl.sortable) { // 避免重复初始化 new Sortable(listEl, { group: "nested", handle: ".handle", animation: 150, fallbackOnBody: true, swapThreshold: 0.65, onEnd: function(evt) { var order = []; $(".category-list li").each(function(index, element) { order.push({ id: $(element).data("id"), parent_id: $(element).closest("ul").closest("li").data("id") || null, position: index }); }); // 拖拽后检查目标li是否有ul,没有则创建并重新初始化 $(".list-group-item").each(function() { if ($(this).find(">.category-list").length === 0) { $(this).append('<ul class="list-group category-list"></ul>'); initSortable(); } }); } }); } }); } initSortable(); });
说明
- 每个可作为父节点的
<li>都配备了空ul容器,Sortable可绑定这些容器接收拖拽项 - 修复重复ID问题,确保选择器正常工作
- 新增
initSortable函数,支持动态添加ul后重新初始化,避免遗漏
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

