写在世界杯当中...
好吧,当别人刷世界杯的时候,我还在刷拖拽的bug...
这个确实是给自己挖的坑
整理了一下拖拽坑的几个思路
首先上个API
在拖动目标上触发事件 (源元素):
ondragstart - 用户开始拖动元素时触发
ondrag - 元素正在拖动时触发
ondragend - 用户完成元素拖动后触发
释放目标时触发的事件:
ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
ondrop - 在一个拖动过程中,释放鼠标键时触发此事件
1,该死的拖拽居然是350毫秒才执行一次?!requestanimationframe 60毫秒执行一次才能感觉到流畅好不。这个说真的还不如用setTimeout来模拟了。但是用mouseevent来模拟拖拽事件也确实太麻烦了,而且项目里面还有用到mouseevent的地方。不过350毫秒的设计我想了一下,跟接下来的槽点估计有点关系。
这个果然是用来节流的,用mouseMove来模拟拖拽的时候要节流。不过我还是觉得这个要是能自己设置才最好。
2,drag事件没有方向性可言。这意味着在猜测鼠标移动的方向上要排除一些手滑的噪点,最好的方法是用线性回归的方法去掉那些出问题的点,这个方法有点难写,回头研究python的时候打算研究下。目前还是用去掉特别奇葩点的方法来猜测方向的。用的是两次位置的差值来看趋势的方法。(这里我觉得用350毫秒就是给我们确定方向才设计这么长时间的)
3,最奇葩的点有哪些呢?首先是ondrag事件的最后一帧鼠标位置要回到原点...这个事件还发生在ondragend的事情之前。也对,ondrag事件执行完了才执行ondragend,但是这样ondragend里面就拿不到最后的坐标位置了。解决的思路有两个,第一种就是采用事件循环,将ondrag最后一帧送进setTimeout里面去让它一万年后再发生。第二种是发生鼠标位置为(0,0)的时候就无视。后面这种方法要好一些。还有一个奇葩的点是在第一帧的时候,计算出来的鼠标位置和实际的位置差了一点。这个是控制对象的实际位置和鼠标有一定的差距,一下子调整不到鼠标的位置上来。我解决的方式是加个次数控制器,在大于3的时候,就是基本对象跟着鼠标开始跑了以后才让对象移动。一头一尾,两个最气人的地方。
4,最坑的地方。拖拽的时候会很贴心的给你把拖拽的对象转成图片跟着鼠标走。但是这个图片默认会加个透明度!这个透明度是无法去掉的,给了个API可以将这个图片换走,但是换走的图片还是会加透明度。仔细的翻过全部的API了没有办法去掉这个透明,想要去掉透明度怎么办?方法还是有的,用两个对象,一个对象是透明的就是用来拖拽的,另一个对象就是用来展示用的,两个对象一起跟着对象跑。就是在我们展示的DOM结构上贴上一个透明的拖拽层。
5,这些都是在react封装的ondrag的方法上得出的结果,我觉得还是有必要在原生的情况下实验下,不能相信react封装的方法和js原生的方法100%一样。还是那个思路,框架来用的,不能尽信。
最后提醒下自己:
没事就不要在没有redux的情况下玩什么兄弟之间的传参。坑到死。
网友评论