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

升级jQuery 1.11至3.x时出现Uncaught TypeError循环结构转JSON错误

解决jQuery 3.x升级后JSON.stringify循环结构错误

问题原因

控制台报错Uncaught TypeError: Converting circular structure to JSON,是因为Nestable插件的serialize方法中,直接通过$.extend({}, li.data())提取了元素的所有数据。在jQuery 3.x中,元素的data()会包含插件绑定的实例对象(比如代码里的nestable插件实例),这个实例又反向关联了DOM元素,形成循环引用,导致JSON无法序列化。

修复方案

修改serialize方法中提取元素数据的逻辑,只保留需要的自定义数据,或者排除插件自动添加的循环引用属性。

方案1:明确指定需要序列化的字段(推荐)

如果自定义数据是特定字段(比如id、title等),直接提取这些字段,避免混入插件内部数据:

serialize: function()
{
    var data,
        depth = 0,
        list  = this;
        step  = function(level, depth)
        {
            var array = [ ],
                items = level.children(list.options.itemNodeName);
            items.each(function()
            {
                var li   = $(this),
                    // 只提取你需要的自定义数据字段
                    item = {
                      id: li.data('id'),
                      title: li.data('title')
                      // 添加你实际用到的其他字段
                    },
                    sub  = li.children(list.options.listNodeName);
                if (sub.length) {
                    item.children = step(sub, depth + 1);
                }
                array.push(item);
            });
            return array;
        };
    data = step(list.el.find(list.options.listNodeName).first(), depth);
    return data;
}

方案2:过滤插件自动添加的属性

如果需要保留所有自定义数据,只排除插件添加的nestable和nestable-id属性:

serialize: function()
{
    var data,
        depth = 0,
        list  = this;
        step  = function(level, depth)
        {
            var array = [ ],
                items = level.children(list.options.itemNodeName);
            items.each(function()
            {
                var li   = $(this),
                    rawData = li.data(),
                    // 过滤掉插件自动添加的循环引用属性
                    item = Object.fromEntries(
                      Object.entries(rawData).filter(([key]) => !['nestable', 'nestable-id'].includes(key))
                    ),
                    sub  = li.children(list.options.listNodeName);
                if (sub.length) {
                    item.children = step(sub, depth + 1);
                }
                array.push(item);
            });
            return array;
        };
    data = step(list.el.find(list.options.listNodeName).first(), depth);
    return data;
}

为什么jQuery 1.11没有这个问题?

在旧版本jQuery中,插件实例可能没有被存入元素的data集合,或者data()方法的返回结构不包含这类循环引用的对象,因此序列化时不会触发错误。升级到3.x后,jQuery对data的存储机制有调整,导致插件实例被包含在返回结果中,进而引发循环引用。

内容的提问来源于stack exchange,提问作者Shawn Purdy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:25:20