![696fd610475409ebcbdb94bc98780f19.png](https://img-blog.csdnimg.cn/img_convert/696fd610475409ebcbdb94bc98780f19.png)
Photo by carlos hevia on 500+ Drag Pictures [HD] | Download Free Images on Unsplash
什么是 drag drop? 来自官方网站的描述:
The @angular/cdk/drag-drop module provides you with a way to easily and declaratively create drag-and-drop interfaces, with support for free dragging, sorting within a list, transferring items between lists, animations, touch devices, custom drag handles, previews, and placeholders, in addition to horizontal lists and locking along an axis.
简单来说, drag drop 能够帮助你声明式地, 方便地创建可拖拽元素.
这篇会探究以下四个 demo 所体现的 drag drop 一些 feature 是如何实现的:
- Basic Drag & Drop
- Drag & Drop with a handle
- Drag & Drop boundary
- Drag & Drop position locking
![d327e5bd9ade587ee0280d6b29d3de6d.png](https://img-blog.csdnimg.cn/img_convert/d327e5bd9ade587ee0280d6b29d3de6d.png)
drag drop 最简单的用法是在组件或 HTML 元素上声明一个 cdkDrag
指令, 我们将通过追踪该指令的生命周期与其所创建的一些 listener 来探究 drag drop 的运行机制. 具体而言, 这篇文章的内容会包含以下几个主题:
cdkDrag
的初始化, 以及相关类的初始化- 监听用户按下光标 (可能是按下鼠标左键, 或者是按下触屏), 并准备好处理后续的拖拽事件
- 根据用户光标的移动来调整组件或元素的位置
- 当用户松开光标时结束这次拖拽
有关于 container 的内容将会在下一篇文章中叙述.
第一阶段: 初始化
cdkDrag
你可以在这个文件 directives/drag.ts 中找到该类的实现 (为了方便你阅读源码, 我给一些文件, 类和方法添加了链接).
当你在一个 HTML 元素上声明了该指令时, 它在初始化过程中做了如下几件事情 (参考它的 constructor 和 afterViewInit 钩子):
if (dragDrop) {
this._dragRef = dragDrop.createDrag(element, config);
} else {
this._dragRef = new DragRef(element, config, _document, _ngZone, viewportRuler,
dragDropRegistry);
}
this._dragRef.data = this;
this._syncInputs(this._dragRef);
this._proxyEvents(this._dragRef);
- 实例化
DragRef
对象, 拖拽逻辑主要由该对象负责完成. 这个对象十分重要, 我们待会儿再详细讨论它, 先看下其他代码做了什么. _syncInputs
方法会将指令的一些参数同步到DragRef
对象上. 在该方法中,cdkDrag
订阅了DragRef
的 <