0

0

jQuery UI Sortable 动态更新不可拖拽项的正确实践

花韻仙語

花韻仙語

发布时间:2026-02-21 12:56:01

|

459人浏览过

|

来源于php中文网

原创

jQuery UI Sortable 动态更新不可拖拽项的正确实践

本文详解 jQuery UI Sortable 中动态控制列表项可拖拽状态的核心问题:当通过 addClass/removeClass 切换 .non-sortable-item 类后,"option", "items" 更新失效,必须通过 destroy + 重新初始化才能生效。

本文详解 jquery ui sortable 中动态控制列表项可拖拽状态的核心问题:当通过 `addclass`/`removeclass` 切换 `.non-sortable-item` 类后,`"option", "items"` 更新失效,必须通过 `destroy` + 重新初始化才能生效。

在构建可排序图像上传组件时,一个常见需求是:已上传的图片

  • 允许拖拽排序,而空的“上传占位符”
  • 必须始终不可拖拽(即视觉上固定在末尾)
  • 。你可能尝试用 jQuery UI Sortable 的 items 选项配合 CSS 类(如 li:not(.non-sortable-item))实现该逻辑,并在上传/删除图片时动态增删类名与刷新配置:

    // ❌ 错误做法:仅更新 items 选项或调用 refresh
    $("#sortableList").sortable("option", "items", "li:not(.non-sortable-item)");
    // 或
    $("#sortableList").sortable("refresh");

    但实际运行中会发现:初始状态正常(占位符不可拖),一旦执行过“删除图片 → 再次上传”操作后,原本应不可拖的占位符突然变得可拖了——即使 DOM 上仍存在 class="non-sortable-item",且 items 选项也已重设。

    根本原因:jQuery UI Sortable 的 items 选项不可热更新

    jQuery UI Sortable 在初始化时会一次性解析 items 选择器并缓存匹配的可拖拽元素集合;后续调用 "option", "items" 仅修改内部配置值,并不会重新扫描 DOM 或重建可拖拽元素列表。refresh() 方法同样只重置当前已知可拖元素的位置和样式,不响应 items 选择器变更。因此,当 .non-sortable-item 类动态增删导致可拖元素集合实际变化时,Sortables 仍按旧缓存执行,造成行为错乱。

    ✅ 正确解法:销毁并重建实例

    唯一可靠的方式是显式销毁现有 Sortable 实例,再以更新后的 items 配置重新初始化

    AMiner
    AMiner

    AMiner——新一代智能型科技情报挖掘与服务系统,能够为你提供查找论文、理解论文、分析论文、写作论文四位一体一站式服务。

    下载
    // ✅ 正确:销毁 + 重建(在 uploadNewImage 和 deleteUploadedImage 中统一调用)
    function refreshSortable() {
      $("#sortableList").sortable("destroy");
      $("#sortableList").sortable({
        items: "li:not(.non-sortable-item)", // 确保每次重建都使用最新规则
        placeholder: "ui-sortable-placeholder", // 可选:添加拖拽占位样式
        tolerance: "pointer"
      });
    }
    
    // 在 uploadNewImage 中(移除 non-sortable-item 类后):
    $('#imageListItem_'+imageNumber).removeClass('non-sortable-item');
    refreshSortable(); // ? 关键:重建实例
    
    // 在 deleteUploadedImage 中(添加 non-sortable-item 类后):
    $('#imageListItem_'+imageIndex).addClass('non-sortable-item');
    refreshSortable(); // ? 关键:重建实例

    ? 注意:refreshSortable() 应在所有影响 items 选择器匹配结果的 DOM 操作(如 addClass/removeClass、show/hide、appendTo)完成后立即调用,确保重建时 DOM 状态与预期一致。

    完整优化示例(关键片段)

    $(document).ready(function() {
      // 初始初始化
      refreshSortable();
    });
    
    function uploadNewImage(thisObject, e) {
      const imageNumber = thisObject.getAttribute("imageIndex");
      const imageFile = e.target.files[0];
    
      // ...(原有图片处理逻辑)...
    
      // 移除不可拖类,显示图片
      $('#imageListItem_'+imageNumber).removeClass('non-sortable-item');
      $('#enableFileUpload_'+imageNumber).hide();
      $('#deleteUploadImageSymbol_'+imageNumber).show();
    
      // 显示下一个占位符(如有)
      $('*[id*=imageListItem_]:hidden').first().show();
    
      // ✅ 重建 Sortable —— 这是核心修复点
      refreshSortable();
    }
    
    function deleteUploadedImage(imageIndex) {
      // ...(原有清理逻辑)...
    
      // 隐藏图片区域,显示上传占位符
      $('#imageItem_'+imageIndex).css('background-image', 'none');
      $('#deleteUploadImageSymbol_'+imageIndex).hide();
      $('#enableFileUpload_'+imageIndex).show();
    
      // 将该 <li> 移至末尾并标记为不可拖
      const $item = $('#imageListItem_'+imageIndex);
      $item.addClass('non-sortable-item').hide().appendTo('#sortableList');
    
      // ✅ 重建 Sortable
      refreshSortable();
    }

    注意事项与最佳实践

    • 性能考量:虽然销毁重建略重于 refresh(),但在图像上传场景(通常 ≤10 项)中无感知;若列表极大,可封装防抖逻辑,但本例无需过度优化。
    • 事件绑定安全:destroy() 不会影响
        上的原生事件监听器(如 click),但会清除 Sortable 自身绑定的拖拽事件。由于你的业务逻辑(上传/删除)均通过独立函数触发,无兼容风险。
    • 避免重复初始化:确保 refreshSortable() 内部不重复调用 sortable()(例如检查是否已初始化),或直接在 ready 中初始化一次,后续只调用 destroy+sortable。
    • 现代替代建议:长期项目可考虑迁移到 SortableJS(原生、轻量、支持动态 filter 选项),其 option('filter', '.non-sortable-item') 可实时生效,无需销毁重建。

    通过 destroy + 重建的方式,你将彻底解决 jQuery UI Sortable 动态控制可拖拽项的顽疾,确保用户交互逻辑始终符合设计预期。

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    通义千问
    通义千问

    阿里巴巴推出的全能AI助手

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    jquery插件有哪些
    jquery插件有哪些

    jquery插件有jQuery UI、jQuery Validate、jQuery DataTables、jQuery Slick、jQuery LazyLoad、jQuery Countdown、jQuery Lightbox、jQuery FullCalendar、jQuery Chosen和jQuery EasyUI等。本专题为大家提供jquery插件相关的文章、下载、课程内容,供大家免费下载体验。

    155

    2023.09.12

    jquery怎么操作json
    jquery怎么操作json

    操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

    322

    2023.10.13

    jquery删除元素的方法
    jquery删除元素的方法

    jquery可以通过.remove() 方法、 .detach() 方法、.empty() 方法、.unwrap() 方法、.replaceWith() 方法、.html('') 方法和.hide() 方法来删除元素。更多关于jquery相关的问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

    403

    2023.11.10

    jQuery hover()方法的使用
    jQuery hover()方法的使用

    hover()是jQuery中一个常用的方法,它用于绑定两个事件处理函数,这两个函数将在鼠标指针进入和离开匹配的元素时执行。想了解更多hover()的相关内容,可以阅读本专题下面的文章。

    512

    2023.12.04

    jquery实现分页方法
    jquery实现分页方法

    在jQuery中实现分页可以使用插件或者自定义实现。想了解更多jquery分页的相关内容,可以阅读本专题下面的文章。

    271

    2023.12.06

    jquery中隐藏元素是什么
    jquery中隐藏元素是什么

    jquery中隐藏元素是非常重要的一个概念,在使用jquery隐藏元素之前,需要先了解css样式中关于元素隐藏的属性,比如display、visibility、opacity等属性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    126

    2024.02.23

    jquery中什么是高亮显示
    jquery中什么是高亮显示

    jquery中高亮显示是指对页面搜索关键词时进行高亮显示,其实现办法:1、先获取要高亮显示的行,获取搜索的内容,再遍历整行内容,最后添加高亮颜色;2、使用“jquery highlight”高亮插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    180

    2024.02.23

    jQuery 正则表达式相关教程
    jQuery 正则表达式相关教程

    本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

    50

    2026.01.13

    pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
    pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

    本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

    796

    2026.02.13

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    jQuery 教程
    jQuery 教程

    共42课时 | 6.4万人学习

    HTML+CSS基础与实战
    HTML+CSS基础与实战

    共132课时 | 11.4万人学习

    tp6+adminlte搭建通用后台
    tp6+adminlte搭建通用后台

    共39课时 | 5.8万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号