拖拽节点
拖拽节点的逻辑都封装在dragdrop.js这个文件里,主要方法为 dragStart 、 drag 、 dragEnd 。
dragStart
在一次拖拽行为中,该方法只执行一次,因此适合做一些初始化工作,此时代码如下:
dragStart(el, offsetX, offsetY) { // 要拖拽的节点 const dragNode = utils.searchUp(el, 'dragrid-item'); // 容器 const dragContainer = utils.searchUp(el, 'dragrid'); // 拖拽实例 const instance = cache.get(dragContainer.getAttribute('name')); // 拖拽节点 const dragdrop = dragContainer.querySelector('.dragrid-dragdrop'); // 拖拽节点id const dragNodeId = dragNode.getAttribute('dg-id'); // 设置拖拽节点 dragdrop.setAttribute('style', dragNode.getAttribute('style')); dragdrop.innerHTML = dragNode.innerHTML; instance.current = dragNodeId; const offset = utils.getOffset(el, dragNode, {offsetX, offsetY}); // 容器偏移 const containerOffset = dragContainer.getBoundingClientRect(); // 缓存数据 this.offsetX = offset.offsetX; this.offsetY = offset.offsetY; this.dragrid = instance; this.dragElement = dragdrop; this.dragContainer = dragContainer; this.containerOffset = containerOffset; }
1.参数el为拖拽句柄元素,offsetX为鼠标距离拖拽句柄的横向偏移,offsetY为鼠标距离拖拽句柄的纵向偏移。
2.通过el可以向上递归查找到拖拽节点(dragNode),及拖拽容器(dragContainer)。
3.dragdrop元素是真正鼠标控制拖拽的节点,同时与之对应的布局节点会变为占位节点(placeholder),视觉上显示为阴影效果。
4.设置拖拽节点其实就将点击的dragNode的innerHTML设置到dragdrop中,同时将样式也应用过去。
5.拖拽实例,其实就是dragrid.vue实例,它在created钩子函数中将其实例缓存到cache中,在这里根据name就可以从cache中得到该实例,从而可以调用该实例中的方法了。
6.instance.current = dragNodeId; 设置之后,dragdrop节点及placeholder节点的样式就应用了。
7.缓存数据中的offsetX、offsetY是拖拽句柄相对于节点左上角的偏移。
drag
发生拖拽行为之后,鼠标move都会执行该方法,通过不断更新拖拽节点的样式来是节点发生移动效果。
drag(event) { const pageX = event.pageX, pageY = event.pageY; const x = pageX - this.containerOffset.left - this.offsetX, y = pageY - this.containerOffset.top - this.offsetY; this.dragElement.style.cssText += ';transform:translate('+ x +'px, '+ y +'px)'; }
主要是计算节点相对于容器的偏移:鼠标距离页面距离-容器偏移-鼠标距离拽节点距离就为节点距离容器的距离。
dragEnd
主要是重置状态。逻辑比较简单,就不再细说了。