不过性能最优的方式还是要为被拖拽的那个元素触发composite layer(可以叫它合成层),因为现在浏览器一般都是 合成化渲染,并且大部分 光栅化(就是把元素形状的几何数据描述变成像素描述的过程,可以理解成矢量变成位图)过程都是在CPU上进行的,如果不把被拖拽的那个元素触发成为 合成层 那么CPU就会重复的paint这个元素,这是不合理的(CPU paint的过程比较耗时),所以应该让CPU尽量少的paint这个元素,最好只paint一次,之后的拖拽(也就是位移,甚至是旋转啊、缩放啊等这些仿射变换) 都可以直接交给GPU在合成(composited)的时候来做,这也就是所谓的硬件加速机制。
合成过程就是把几个合成层(一个合成层可以是 一个元素或多个元素组合经过CPU 光栅化后得到的图片)根据各个层的几何顶点信息、矩阵描述、透明度、blend效果等信息使用GPU进行重新的光栅化渲染到一张直接投影到屏幕上的图片上(帧缓冲区 framebuffer),然而这里的光栅化是非常快的,不同于CPU的那个光栅化的过程。原因大致如下:
一、因为这个时候的渲染只是把一张现成的位图合成到一起(就像纹理贴图,可以简单理解成像素值的简单计算和拷贝)。而不像CPU光栅化,它是将非常复杂的几何数据(是由浏览器分析dom的css样式所得到的)通过一系列复杂的逻辑计算后得到一个像素最后得到一张图片。
二、因为GPU有非常多个处理单元在并行的处理这些简单的渲染,它的计算吞吐量是很大的。而CPU的处理单元非常少,做强逻辑的计算非常适合,但是做这种简单的加减乘除计算不如GPU快(人多力量大)。
因为需要计算元素的位置变化,所以需要掌握几个关于位置的api
点击需要拖动元素时,获取该元素的初始位置。
鼠标移动期间 获取元素当前的位置信息
计算
进行事件监听
拖拽的实现原理:通过事件mousedown(事件的触发) →mousemove(事件的控制) →mouseup(事件的清除),拖拽的过程就是mousemove阶段;
问题产生的原因:因为mousemove 的间隔性触发,当两次mousemove事件触发的间隔中,鼠标移动距离出了element的范围,就会产生鼠标脱离element范围,拖拽就停止,
解决方法: 将mousemove事件挂在docment,而不是对应的element,此时鼠标滑动只要不出docment范围就不会触发上述情况。
拖动事件完成的动作时是:mousedown(事件的触发) →mousemove(事件的控制) →mouseup(事件的清除) 但是mouseup的时候 同时会触发 点击事件(如果元素上面有点击事件的话)
处理办法:记录mousedown(记录开始时间) →mousemove→mouseup(记录结束时间) 的时间 根据时间长短判断是进行了点击事件还是进行了拖拽事件。
正常需求的话 就希望拖拽元素只在屏幕的可视范围内进行拖拽,不能跑出去。
在onmousemove 中添加边缘控制就好,具体范围可以根据具体需求更改。