尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Draggable(@shopify/draggable)完整更新日志解析:从 v1.0.0-beta 到 v1.2.1 的版本演进与技术脉络

Draggable(@shopify/draggable)完整更新日志解析:从 v1.0.0-beta 到 v1.2.1 的版本演进与技术脉络 Draggableshopify/draggable完整更新日志解析从 v1.0.0-beta 到 v1.2.1 的版本演进与技术脉络【免费下载链接】draggableThe JavaScript Drag Drop library your grandparents warned you about.项目地址: https://gitcode.com/gh_mirrors/dr/draggable本文以仓库根目录 CHANGELOG.md 为主线系统梳理shopify/draggable从 2017 年首个 beta 版本到 1.2.1 正式版的全部变更记录并结合 src 目录下的核心源码Draggable、Sortable、Mirror、SortAnimation、SwapAnimation、ResizeMirror、Announcement 等与 package.json 构建配置逐条还原每个版本迭代背后的 API 变化、插件机制、事件模型与工程化演进。读完本文你将掌握该库的事件生命周期、插件/传感器架构、镜像Mirror机制、可排序动画的实现原理并能读懂任何一个历史版本的 CHANGELOG 条目所对应的实际代码。一、项目定位与版本总览shopify/draggable是一个将浏览器原生拖拽事件抽象为统一 API 的 JavaScript 拖拽库。正如 README.md 所述Draggable 本身不执行任何排序行为但承担了重体力活——创建 mirror、派发事件、管理 sensor 事件、让元素变得可拖拽在其之上构建了Sortable、Droppable、Swappable三个附加模块。从 package.json 可以看到仓库当前版本为1.2.1。CHANGELOG 覆盖了两个阶段阶段版本区间发布时间特征Beta 阶段v1.0.0-beta ~ v1.0.0-beta.132017-09 至 2021-05功能高速迭代正式阶段v1.0.0 ~ v1.2.1引入 changeset 管理版本随后进入维护模式CHANGELOG 中正式版本条目v1.0.0采用 changeset 风格的### Patch Changes/### Minor Changes记录而早期 beta 条目则使用经典的### Added/### Changed分类读者可从条目格式直接分辨版本记录方式的分水岭。二、事件系统从Emitter到完整事件模型的成型2.1 beta.5Emitter 类与事件分发能力的诞生v1.0.0-beta.52018-03-02首次AddedEmitterclass for event emitting for draggable这是整个事件体系的地基。在 Emitter.ts 中实现了on/off/trigger三件套而 Draggable.js 将这三个方法直接暴露到实例上形成draggable.on(drag:start, cb)的链式调用 API。2.2 beta.4 至 beta.6事件从增补到修正beta.4新增MirrorCreateEvent支持取消镜像创建SortableStartEvent在 beta.3 被补发。beta.5将SensorEvent加入导出SnapEvent上增加snappableElement属性。beta.6为Droppable新增DroppableStart/DroppableStop事件并把DroppableOver更名为DroppableDropped、DroppableOut更名为DroppableReturned。beta.132021-05-17新增mirror:moved事件并支持按 ESC 键取消拖拽。2.3 beta.12drag:stopped补全拖拽收尾语义beta.12 新增drag:stopped事件它will be fired after drag finished在拖拽结束后触发与可取消的drag:stop形成前后呼应。在 DragEvent.ts 中可以看到两者的分工DragStopEventdrag:stop标记static cancelable true可被取消以阻止放置DragStoppedEventdrag:stopped不可取消仅在收尾完成后通知。实际触发顺序可在 Draggable.js 的[dragStop]方法中验证先 triggerdrag:stop随后移除 source、清理 class、延迟清理source:placedplacedTimeout默认 800ms最后 triggerdrag:stopped。2.4 beta.11按事件类型推断回调参数类型beta.11 支持根据事件类型设置回调函数的参数类型对应到 TypeScript 定义中Draggable#on(type, callback)的泛型推断能力使drag:over等事件的回调参数能自动获得DragOverEvent类型提示。三、插件体系从零散功能到可插拔架构3.1 默认插件与静态暴露beta.4起默认Draggable插件以静态属性暴露Draggable.Plugins同时AbstractPlugin成为所有插件的基类。beta.5加入Announcement插件屏幕阅读器支持、Mirror插件的cursorOffset选项、Scrollable插件的scrollableElements选项并新增AutoScroll后被重命名为Scrollable。beta.7新增ResizeMirror插件。beta.102020-06-18新增SortAnimation插件。当前 Draggable.js 中Draggable.Plugins {Announcement, Focusable, Mirror, Scrollable}而传感器为Draggable.Sensors {MouseSensor, TouchSensor}ForceTouchSensor自 beta.2 起不再默认包含。3.2 beta.11exclude选项精确裁剪默认插件/传感器beta.11 新增exclude选项用于禁用默认插件与传感器。其底层实现在 Draggable.jsconst defaultPlugins Object.values(Draggable.Plugins).filter( (Plugin) !this.options.exclude.plugins.includes(Plugin), ); const defaultSensors Object.values(Draggable.Sensors).filter( (sensor) !this.options.exclude.sensors.includes(sensor), ); this.addPlugin(...[...defaultPlugins, ...this.options.plugins]); this.addSensor(...[...defaultSensors, ...this.options.sensors]);配合exclude的使用示例const draggable new Draggable(document.querySelectorAll(.container), { exclude: { plugins: [Draggable.Plugins.Announcement], // 禁用无障碍朗读 sensors: [Draggable.Sensors.TouchSensor], // 禁用触摸传感器 }, });同时 beta.11 修复了delay与distance并置时的拖拽启动并发问题并修复镜像文字模糊与镜像误追加问题。3.3 动态增删 APIbeta.3 为Draggable扩展了动态 API全部可在 Draggable.js 中找到实现API作用源码位置addSensor/removeSensor动态增删传感器Draggable.jsaddPlugin/removePlugin动态增删插件Draggable.jsaddContainer/removeContainer动态增删容器Draggable.jsisDragging()查询当前是否在拖拽Draggable.js3.4 无障碍Announcement 插件细节beta.8 将 Announcement 插件从innerHTML切换为textContent避免 XSS 注入风险。在 Announcement.js 中消息通过创建 div 写入draggable-live-regionaria-liveassertive、rolelog实现屏幕阅读器朗读默认expire: 7000ms 后自动移除。默认朗读文案定义在 Draggable.js 的defaultAnnouncements如drag:start时朗读 Picked up ...。四、Mirror 镜像机制拖拽视觉反馈的进化4.1 从跟随手到可取消、可约束、可过滤beta.4新增source:originalclass 选项、MirrorCreateEvent可取消镜像创建并修复拖拽开始被取消时镜像的遗留问题同时移除镜像创建时的 margin。beta.5新增 Mirror 插件的cursorOffset选项修复constrainDimensions选项。beta.92019-08-26新增thresholdX/thresholdY镜像选项。beta.10修复constrainDimensions生效且未使用固定宽度时镜像尺寸计算错误的问题。beta.13新增mirror:moved事件。4.2 Mirror 的默认选项与阈值过滤原理Mirror.js 中的默认选项export const defaultOptions { constrainDimensions: false, xAxis: true, yAxis: true, cursorOffsetX: null, cursorOffsetY: null, thresholdX: null, thresholdY: null, };thresholdX/thresholdY的实现位于 Mirror.js当设置阈值后只有当指针移动距离超过阈值时才更新镜像位置并触发mirror:move从而实现拖拽抖动过滤。appendTo选项支持字符串选择器、HTMLElement或函数三种形式Mirror.jsbeta.4 起其默认值从document.body改为源元素的父节点。4.3 镜像生命周期事件链镜像从创建到销毁依次触发mirror:create可取消→mirror:created→mirror:attached→mirror:move可取消→mirror:moved→mirror:destroy可取消。这一链条在 Mirror.js 中完整实现其中mirror:created之后通过 Promise 链完成尺寸计算、偏移计算、class 添加与初始定位Mirror.js。五、Sortable 排序索引修正与跨容器移动5.1 核心修复记录beta.3修复SortableSortedEventsortable:sorted返回错误索引的问题并保证SortableStartEvent正确触发。beta.4修复 Sortable 排序逻辑——计算时排除 mirror 与原始 source 元素。beta.12修复嵌套 sortable场景下oldIndex值错误与同容器判断错误。beta.9修复SortableEvent的over和overContainer属性错误。5.2 索引计算源码印证在 Sortable.js 中排序时先记录oldIndex this.index(source)完成move()后通过newIndex this.index(event.source)计算新索引随后触发携带oldIndex/newIndex的SortableSortedEvent。getSortableElementsForContainer在 Draggable.js 中通过过滤掉originalSource与mirror保证排序计算不受影子元素干扰——这正是 beta.4 修复的核心。5.3 可取消的排序/交换事件beta.3 引入sortable:sort与swappable:swap事件二者均可取消以阻止排序/交换发生相关事件类型定义在 SortableEvent.ts 与 SwappableEvent.ts。六、动画插件SortAnimation 与 SwapAnimation6.1 beta.10 新增 SortAnimationSortAnimation插件为排序过程提供平滑位移动画。其核心思想在 SortAnimation.js监听sortable:sort记录容器内每个可拖拽元素的offsetTop/offsetLeftSortAnimation.js监听sortable:sorted根据oldIndex/newIndex计算受影响元素区间并放入下一帧requestAnimationFrame执行animate()SortAnimation.jsanimate()通过translate3d反向位移配合 CSStransition实现回弹动画动画结束后由transitionend事件清理内联样式SortAnimation.js。默认选项为{duration: 150, easingFunction: ease-in-out}可通过draggable.options.sortAnimation覆盖SortAnimation.js。6.2 beta.3 起步的 SwapAnimationSwapAnimation现为 TypeScript 实现见 SwapAnimation.ts为Swappable提供两元素互换动画。默认选项为{duration: 150, easingFunction: ease-in-out, horizontal: false}SwapAnimation.ts其中horizontal: true时交换动画沿水平轴进行SwapAnimation.ts。七、传感器Sensors多输入源统一抽象7.1 传感器家族的建立与调整beta首版即内置传感器机制。beta.2ForceTouchSensor不再默认包含修复MouseSensor的原生拖拽事件误触发。beta.3所有传感器改为监听document而非每个容器TouchSensor在不使用preventDefault的情况下阻止页面滚动MouseSensor在 delay 期间阻止原生元素开始拖拽。beta.9修复MouseSensor中contextmenu的误阻止。beta.13修复当目标不在 handle 或 draggable 元素内时 sensor 提前 return的问题。7.2 当前传感器构成当前 Sensors/index.js 暴露DragSensor、ForceTouchSensor、MouseSensor、TouchSensor其中默认启用的是MouseSensor与TouchSensorDraggable.jsForceTouchSensor需要显式addSensor或通过options.sensors传入import {Draggable, Sensors} from shopify/draggable; const draggable new Draggable(document.querySelectorAll(.container), { sensors: [Sensors.ForceTouchSensor], });传感器统一将底层事件鼠标、触摸、原生 drag、3D Touch归一化为drag:start/drag:move/drag:stop/drag:pressure等 SensorEvent定义见 SensorEvent.tsDraggable 在document上以捕获阶段监听这些事件Draggable.js。八、构建与工程化演进8.1 打包工具的两次革命beta.3引入 bundle split每个模块输出独立 JS bundle并提供面向 IE11 的 legacy bundle。v1.1.0PR #574构建从 webpack 迁移到 rollup导入路径发生变更Import paths have changed。v1.1.1PR #582构建产物统一重命名为.cjs与.mjs后缀并解析 TS 声明文件的绝对路径、清理构建目录中的代码注释。当前 package.json 的产物出口为main: build/cjs/index.cjs, module: build/esm/index.mjs, esnext: build/esnext/index.mjs, types: ./index.d.ts8.2 工程化配套beta.5接入 greenkeeper依赖管理、codecov覆盖率追踪、GitHub issue/PR 模板、examples 的 yarn 脚本与 esdoc 脚本Node 版本从8.9.1升至8.9.4。v1.0.0引入 changeset 依赖统一管理版本发布。v1.1.3新增AutoBind装饰器AutoBind.tsResizeMirror测试转为 TypeScriptResizeMirror.test.ts并修复 VSCode 搜索排除生成文件/目录。v1.1.4为 npm 包增加 provenance来源证明声明。v1.2.0构建与 CI 升级至 Node v20。v1.2.1从发布流程中移除 npm token安全加固。8.3 TypeScript 迁移路线CHANGELOG 清晰记录了渐进式 TS 迁移v1.0.1ResizeMirror转为 TypeScriptv1.1.2PR #579批量将CollidableEvent、SensorEvent、SwappableEvent、SortableEvent、DroppableEvent、MirrorEvent、SnappableEvent、DraggableEvent转为 TypeScript同时DragEvent测试转 TSv1.1.3ResizeMirror测试转 TS。如今事件类如 DragEvent.ts、MirrorEvent.ts与动画插件均已采用 TypeScript AutoBind装饰器实现而 Draggable 核心仍为 JS JSDoc。九、关键默认值变更清单升级兼容提醒以下默认值的调整直接影响既有项目行为升级时需重点核对版本变更影响beta.3delay默认值从0改为100拖拽触发需按住 100msbeta.4appendTo默认从document.body改为源元素父节点镜像插入位置变化beta.2ForceTouchSensor不再默认启用3D Touch 场景需显式引入v1.1.0构建工具 webpack → rollup导入路径全部变更v1.1.1产物后缀改为.cjs/.mjs直接引用构建文件的代码需更新当前 Draggable 的完整默认选项可在 Draggable.js 中查看draggable: .draggable-source、handle: null、delay: {}、distance: 0、placedTimeout: 800等其中delay与distance在 beta.9/beta.10 分别被引入并加入 TypeScript 接口distance?: number。十、从 CHANGELOG 到实践版本选择建议若项目仍在使用旧版 webpack 时代的构建产物需注意 v1.1.0 的导入路径变更升级后建议统一从包入口shopify/draggable导入而非直接引用build/下的文件。若涉及嵌套 Sortable请确保版本 ≥ beta.12以获得oldIndex与同容器判断的修复。若需要无障碍拖拽屏幕阅读器朗读Announcement插件自 beta.5 提供、beta.8 起使用安全的textContent建议保持启用。若追求排序/交换动画效果SortAnimationbeta.10与SwapAnimationbeta.3 起步、现为 TS均通过draggable.options.pluginName传入duration/easingFunction配置。关于各模块的详细 API 文档可直接阅读仓库内对应目录Draggable 及其插件/传感器见 src/DraggableSortable / Swappable / Droppable 见 src/Sortable、src/Swappable、src/Droppable通用插件见 src/PluginsTypeScript 使用说明见 doc/typescript.md完整类型声明见 index.d.ts。【免费下载链接】draggableThe JavaScript Drag Drop library your grandparents warned you about.项目地址: https://gitcode.com/gh_mirrors/dr/draggable创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表