Nestable 拖拽后怎么获取更新后的层级结构?

迷人的舒婕 阅读 25

我用 Nestable 实现了一个可拖拽的树形菜单,但拖完之后不知道怎么拿到最新的嵌套结构。文档里说要用 serialize 方法,但我调用后返回的是空数组,是不是哪里没初始化对?

我初始化的代码是这样的:

$('#nestable').nestable({
  maxDepth: 5
});

然后在拖拽结束事件里这样取数据:

$('#nestable').on('change', function() {
  var data = $(this).nestable('serialize');
  console.log(data);
});

结果 data 一直是空的,DOM 结构明明变了啊,到底咋回事?

我来解答 赞 0 收藏
二维码
手机扫码查看
1 条解答
小菊 Dev
这个问题挺常见的,serialize 返回空数组一般是 DOM 结构不符合 Nestable 的要求。

Nestable 对 HTML 结构有严格规定,不是随便一个嵌套的 ul/li 就能工作。你需要确保以下几点:

1. HTML 结构必须符合规范

每个可拖拽项必须是 dd-item,每个层级列表必须是 dd-list,像这样:

<div class="dd" id="nestable">
<ol class="dd-list">
<li class="dd-item" data-id="1">
<div class="dd-handle">Item 1</div>
<ol class="dd-list">
<li class="dd-item" data-id="2">
<div class="dd-handle">Item 2</div>
</li>
</ol>
</li>
<li class="dd-item" data-id="3">
<div class="dd-handle">Item 3</div>
</li>
</ol>
</div>


2. 最关键的一点:每个 dd-item 必须有 data-id 属性

serialize 方法就是靠读取这个 data-id 来构建数组的,没有它就会返回空数组。

3. 完整可用的示例代码

HTML 部分:
<div class="dd" id="nestable">
<ol class="dd-list">
<li class="dd-item" data-id="1">
<div class="dd-handle">菜单项 1</div>
</li>
<li class="dd-item" data-id="2">
<div class="dd-handle">菜单项 2</div>
<ol class="dd-list">
<li class="dd-item" data-id="3">
<div class="dd-handle">子菜单 2-1</div>
</li>
</ol>
</li>
</ol>
</div>


JS 部分:
$('#nestable').nestable({
maxDepth: 5,
// 下面这个很重要,防止初始化时就触发 change 事件
noDragClass: 'dd-nodrag'
});

$('#nestable').on('change', function() {
// serialize 返回的是数组,每个元素包含 id 和 children
var data = $(this).nestable('serialize');
console.log(data);

// 如果你想发送到后端,需要转成 JSON 字符串
var jsonString = JSON.stringify(data);
console.log(jsonString);
});


4. 你可以这样检查问题

在浏览器控制台执行这几行,看看输出什么:

// 检查是否有 data-id
$('.dd-item').map(function() { return $(this).data('id') }).get()

// 检查结构是否正确
console.log($('#nestable').find('.dd-item').length)


如果上面第一个命令返回空数组或者 undefined,那就是 data-id 没加。

5. 动态添加数据时的写法

如果你用 JS 动态生成菜单项,记得一定要加 data-id:

function addItem(text, id) {
return '<li class="dd-item" data-id="' + id + '">' +
'<div class="dd-handle">' + text + '</div>' +
'</li>';
}


基本上就是这些,你对照检查一下你的 HTML 结构,特别是 data-id 是不是每个 item 都有。
点赞
2026-03-12 20:23