上文描述了拖拽标签的场景,本文详述标签移动过程中的定位,以及拖拽前后落位区域的情况。
在鼠标点击->拖动->抬起的过程中,在不同时机均调用了isLocatedToWhere方法,该方法会返回目前被拖拽标签的位置。其基本原理是通过fallInDiv方法由外向内查找各个div容器,判断当前被移动元素的坐标中心点是否落入当前容器内。isLocatedToWhere最终返回一个代表位置的结构如{firestLevel: 1, secondLevel: 1, [thirdLevel: 2]},索引从1开始,
根据不同场景决定需要前两层位置或者也需要第三层位置
下图演示了isLocatedToWhere方法判断位置的逻辑。红框代表的是第一层级,如图’广州’处于第一个逻辑块内,firstLevel: 1;黄框代表第二个层级,'广州’依然处于第一个逻辑块内,secondLevel: 1;蓝框代表第三个层级,'广州’是第二个逻辑块,thirdLevel: 2
1. 移动过程中,触发相应区域高亮
mousemove过程中,调用isLoatedToWhere方法检测目前经过的区域,当拖拽的元素经过时,高亮对应区域,通过改变border样式高亮,此场景只需要firstLevel和secondLevel即可
2. 移动结束后,获取最终位置
mouseup时,通过isLocatedToWhere获取最终被拖拽到的位置,只需firstLevel和secondLevel即可判断,然后将该元素放置到该区域最后一个元素之后,如果还没有该区域,添加为该区域第一个元素
3. 在下部面板内部移动时,获取起始位置
如果是下部面板内部的拖动,通过isLocatedToWhere获取到起始位置,包含firstLevel、secondLevel和thirdLevel。此时需要传入标识标签本身的信息作为参数(type, title, id)
offset偏移量
计算拖拽移动时,始终要考虑滚动条位置
const scrollPositionDrag = document.getElementsByClassName('content')[0].scrollTop
const scrollPositionDrop = document.getElementsByClassName('condition-first-level')[0].scrollTop
在计算纵向坐标时,要分情况考虑将滚动高度计算在内的情况。如以下代码:
if (this.moveType === 1) {
if (scrollPositionDrag > 0) {
odiv.style.top = (odiv.offsetTop - scrollPositionDrag) + 'px'
}
} else {
if (scrollPositionDrop > 0) {
odiv.style.top = (odiv.offsetTop - scrollPositionDrop) + 'px'
}
}
代码在按下鼠标时调用,这里moveType表示拖拽类型。1:从上往下拖拽标签;2:下部面板内部拖拽。可以看到如果滚动条内有高度了需要将元素top位置考虑在内进行计算