专栏名称: 奇舞周刊
《奇舞周刊》是由奇舞团维护的前端技术周刊。除周五外,每天向大家推荐一篇前端相关技术文章,每周五向大家推送周刊汇总内容。
目录
相关文章推荐
前端大全  ·  包含大量加密 JS 代码,知名 ... ·  13 小时前  
湾区财经传媒  ·  小米SU7Ultra、15Ultra,深圳小 ... ·  昨天  
湾区财经传媒  ·  小米SU7Ultra、15Ultra,深圳小 ... ·  昨天  
前端大全  ·  shadcn/ui:2024年最受欢迎的前端项目 ·  4 天前  
前端早读课  ·  【第3463期】使用抽象语法树把低代码配置转 ... ·  2 天前  
51好读  ›  专栏  ›  奇舞周刊

换个角度看拖放

奇舞周刊  · 公众号  · 前端  · 2017-09-25 18:00

正文

编者按:本文由弈晨在众成翻译平台上翻译。今天向大家介绍一个拖放库。


介绍 react-beautiful-dnd

拖拽是一个直观的移动和重排方式。我们已经在 Atlassian 的官方仓库上发布了 react-beautiful-dnd ,它能够使表单在在网页中的拖放变得更加漂亮、自然和容易。

更有物理感

react-beautiful-dnd 的核心设计思想是“物理感”,我们想让用户在拖放的时候感觉在移动身边的物体。对比是最好的说明方式——我们来探讨一些标准拖放行为以及我们如何做的更好。

jquery-sortable

这个例子使用了 jquery-sortable ,非常棒。它的拖放机制是相当标准的,是一个很好的参照物。

移动

直接移动是基本做法

当拖动元素时,其他元素将根据需要消失并重新出现。并且当你放下元素时,它会立即出现在新的位置。

一种更自然的移动方式

在拖拽的时候我们给需要移出自己原先位置的元素添加了动画,以便更清楚地显示拖动效果,这是一种更自然的移动方式。我们也给元素的 drop 添加了动画,这样在移动到新位置时候也会有动效了。在任何时候一个元素的移动行为都不应该是瞬间完成的。

知道何时移动

显然,拖放的交互应该基于用户开始拖动的起始位置。

基于选择点的移动

在上面的例子中,用户按住了第一个元素的右上角。在第二个元素移动到新位置之前,用户需要正确地往下拖拽,因为计算是基于用户最初选择的位置。

基于重心的移动

react-beautiful-dnd 中,正在拖动中的元素对其他元素的影响是基于重心的,不管用户点击何处开始的拖拽。拖动中元素对其他元素的影响所遵循的规则类似一架天平 ⚖️。下面是其中一些规则,考虑到了自然拖动的一些经验,甚至考虑了元素高度可变的情况。

  • 当正在拖动的元素的中心点经过列表的边缘的时候,列表是 拖拽经过 的状态。

  • 当正在拖动的元素的中心位置越过静止元素的边缘时,静止元素将移到拖动元素的路径外。换句话说:一旦一个元素 A 的中心位置越过另一个元素 B 的边缘,B就移开了。

易用性

传统的拖放交互完全是鼠标或触摸交互。 react-beautiful-dnd 还支持 只用键盘 的拖拽交互。这使得一些高端用户能够随心所欲地使用他们操作键盘的经验,以及向以前没用过键盘拖拽的用户开放这些体验。

尊重浏览器

除了支持键盘,我们还审查了键盘快捷键如何与标准浏览器键盘交互。当用户没有拖拽元素时,他们可以像平时那样使用键盘。拖动时,我们会覆盖和禁用浏览器的某些快捷键(如“tab”键),以保证用户的流畅体验。

细致的动画设计

因为元素动来动去,用户很容易被这些动画分心。我们已经调整了各种动画,以确保提示、性能和交互性达到正确的平衡。

最大限度地提高交互性

react-beautiful-dnd 尽力避免了很多地方的不可交互性。用户会感觉是他们在控制界面,而不是等待动画完成才能继续与界面交互。

放置(dropping)

当你放置一个拖拽的元素的时候,它的动作是符合物理特性的(感谢 react-motion )。放置的感觉更符合重力学,更贴近物理世界。

从路径上移出

元素从正在拖拽的元素路径中移出使用 CSS 动画而不是物理变化,通过允许 GPU 处理运动来使性能最大化。设计 CSS 动画曲线是为了计算非拖拽元素 从正在拖拽元素的移动路径上移出

这个动画是这样组成的:

  1. 一个预热期,模仿自然的响应时间

  2. 一个短暂的阶段,快速从路径上移开

  3. 一个长长的结束动画,这样人们就可以在动画的后半部分阅读任何正在运动中的文字。

移出路径时使用的动画曲线

跟其他事件配合得很好

我们已经做了很多事情来确保在提供灵活性的同时让一切保持直观。

慢点击和点击阻塞

当用户在某个元素上点击鼠标时,我们无法确定用户是否正在点击还是拖拽。而且,有时候当用户点击的时候他们可以非常轻地移动光标 ——这被称为慢点击。因此,只有鼠标被按下而且移动到一定距离(拖拽阈值)后,我们才开始拖拽事件,而不是用户只要一开始移动鼠标,有可能用户只是做了一次慢点击。如果拖拽没有超过阈值,那么用户的交互行为就被视为一次普通的点击。如果拖拽超过了阈值,那么交互将被视为拖拽,标准的单击事件不会发生。

这可以让用户把交互的元素包起来,比如锚点,让它不仅仅是一个标准的锚点,也是一个可拖拽的元素。

焦点管理

react-beautiful-dnd 在确保不会影响正常的 tab 文档流方面也下了很多功夫。比如,如果你包装了一个 锚点 标签,用户仍然能够通过 tab 键定位到锚点,而不是定位到包裹着锚点的元素。我们添加了一个 tab-index 给拖拽元素,确保即使没有用常见的交互式的东西(比如 div )包裹,用户仍然可以通过键盘来拖动它。

并不能满足所有人的需求

现在外面有很多 React 拖放交互的库,其中最值得注意的是优秀的 react-dnd 。它提供了一组非常好的拖放原子操作,尤其是与 极其不连贯的 HTML5 拖放特性配合得非常好,真是难以置信的工作。 react-beautiful-dnd 是专为垂直和水平列表构建的高级抽象 。在功能子集内, react-beautiful-dnd 提供了强大,自然和漂亮的拖放体验。然而,它并不像 react-dnd 提供了很多的功能。所以这个库可能不适合你,这取决于你的用例是什么。

工程化

干净、强大的 API

在这个库发布很久以前,人们就期望能有一个声明式的、干净的、强大的 API。它应该很容易上手,并在整个拖放体验上提供正确的控制水准。它是基于对其他库的大量研究以及在构建拖放产品方面的博采众长。

性能

react-beautiful-dnd 被设计得非常高效,这是它与生俱来的特性。它建立在对 React 性能的事先调查之上,你可以阅读 这篇文章 and 另一篇文章 。它被设计成执行每个任务所需的渲染次数最少。

亮点

  • 使用带有记忆功能的连接组件来确保只有有需要渲染的组件才会被渲染,这要感谢 react-redux reselect memoize-one

  • 所有的拖拽动作都被 requestAnimationFrame 节流(throttled),感谢 raf-schd

  • 广泛使用记忆功能,感谢 memoize-one

  • 有条件地禁止当拖拽正在进行时,其他所有可拖放元素的 鼠标事件 ,这样可以阻止浏览器做无用功。你可以阅读 这篇技术文章 来了解更多。

  • 非主要的动画都在 GPU 上完成







请到「今天看啥」查看全文