1、需求描述:对移动端多张图片可以进行拖动排序(例子中使用两排5张图片)
2、实现过程:
主要思想就是能够通过用户手势,捕捉到被拖 动元素以及拖动结束后的被交换元素,通过交换这两个元素实现拖动排序。除此之外,我们还需要获得被拖动元素在拖动过程中的的left和top值,增加拖动过程中的效果。
在这个过程中会用到移动端的手势事件touchstart,touchmove,touchend
首先,需要获得被拖动的目标图片,做法是首先计算出所有图片的一个左上角的left,top值数组,然后根据手势位置是否在[left,left+imgwidth]和[top,top+imgheight]之间来确定目标图片,并且赋值给一个初始值currentindex:
//计算全部图片的left和top
getStartPos() {
let doms = Array.prototype.slice.call(document.getElementsByTagName('li'))
let centerpos = []
doms.map(item => {
centerpos.push({left:item.offsetLeft, top:item.offsetTop})
})
return centerpos
}
//touchstart的事件监听函数
dragStart(ev) {
let centerpos = this.getStartPos()
let target = ev.target, self = this
if(ev.changedTouches) {
this.startX = ev.changedTouches[0].pageX;
this.startY = ev.changedTouches[0].pageY;
} else {
this.startX = ev.clientX;
this.startY = ev.clientY;
}
//鼠标边界性
this.startX >this.clientWidth ? this.startX = this.clientWidth: null
this.startY >this.clientHeight ? this.startY = this.clientHeight: null
//偏移位置 = 鼠标的初始值 - 元素的offset
this.disX = this.startX - target.offsetLeft
this.disY = this.startY - target.offsetTop
//判断用户拖动的是第几张图片
for(let i=0; i<centerpos.length; i++){
let X = centerpos[i].left<this.startX && this.startX<centerpos[i].left + this.elementWid
let Y = centerpos[i].top<this.startY && this.startY<centerpos[i].top + this.elementHeight
if(X && Y){
self.setState({
currentindex:i
})
}
}
this._dragMove = this.dragMove.bind(this);
this._dragEnd = this.dragEnd.bind(this);
}
然后,就是取得移动过程中不断变化的left和top来实现图片移动的效果:
dragMove(ev) {
if(ev.changedTouches) {
this.clientX = ev.changedTouches[0].pageX;
this.clientY = ev.changedTouches[0].pageY;
} else {
this.clientX = ev.clientX