拖拽相关

移动端拖拽相关

touch 事件触发位置问题

touchstarttouchmovetouchend触发的鼠标事件的target都是起始元素,获取不了结束时的元素

解决方案:使用document.elementFromPoint通过pageXpageY去获取元素

const event = e || window.event;
const element = document.elementFromPoint(
  event.changedTouches[0].pageX,
  event.changedTouches[0].pageY
);
if (element) {
  console.table(element);
}

拖拽交互问题

移动端在长时间触摸后拖拽时会触发页面滚动,不能用常规思路实现拖拽

  • 解决方案 1

    在需要起始位置双击,激活拖拽模式,记录当前位置为起始点
    拖拽记录手指划过位置记录为结束点
    在需要结束的位置双击,关闭拖拽模式,记录当前位置为结束点

  • 解决方案 2

    开始拖拽时禁用滚动条

PC 端相关

mouseDowen 偶尔会触发元素的拖动事件

拖拽选取事件的交互采用伪拖拽方式实现,即监听鼠标落下、鼠标划过、鼠标抬起三个事件触发节点的位置,计算出拖拽的时间块。偶尔会触发节点的拖拽事件,设置draggle=false无效

  • 解决方案: 阻止背景块拖拽事件的默认行为
onDragStart={(e) => {
  e.preventDefault();
  e.stopPropagation();
}}

鼠标右键也会触发 mouseDowen

可以通过event.button的值判断点击的是左键还是右键

Chrome浏览器中

  • 0:鼠标左键
  • 1:鼠标中键
  • 2:鼠标右键

其他

判断当前是 PC 端还是移动端

由于移动端各种浏览器的magic标识,区分起来很费力

参考方案:默认为web,如果触发了touch事件视为移动端

多个时间段先求并集再求补集的情况

业务场景:一个专家在某一个天可能有多个排班时间段,需要求取专家没有排班的时间段 例如: 在2023年3月2日专家有三个班次

  • 班次 A:8:00 - 10:00
  • 班次 B:9:30 - 13:00
  • 班次 C:15:00 - 24:00 假设医院的上班时间段为 G:8:00 - 22:00

常规思路

定义一个数组 A1 用于存放禁用时间区间的数组 A1
遍历该专家的三个班次
每次判断数组 A1 中是否有范围
如果没有通过当前范围和时间维度划分出禁用区间放进去
如果有,对比当前范围和禁用区间,逐步减少禁用区间

空间思路

将每一分钟当做一个最小单位
定义一个长度为 24 * 60 - 1 的数组 A2(对应 00:00~23:59)全部填充为 0
遍历这个三个班次
找到班次起始时间对应数组 A2indexS 和截止时间对应的 indexE
将对应区间的数字全部填充为 1
遍历结束后统计数组 A2 中所有 1 的位置可以取到并集,所有 0 的位置可以取到并集的补集