jQuery UI可以很简单的实现元素的拖动,有时候,我们不能使用jQuery UI,或者不想因为拖动就引入一个UI库,就可以自己实现元素的拖动,下面笔者把自己使用jQuery + TouchSwipe组件实现拖动的关键点做简要说明。
HTML拖动的关键点就是修改元素的位置,通过相对偏移来实现,而这个偏移可以通过jQuery的offset方法来实现。
拖动还需要考虑鼠标的移动事件,笔者采用TouchSwipe的swipeStatus事件来实现(手机设备友好的触摸库)。
开始拖动时记录开始位置:
zoom = $("body").css("zoom");
z_idx = $(event.target).css('z-index'),
drg_h = $(event.target).outerHeight(),
drg_w = $(event.target).outerWidth(),
pos_y = $(event.target).offset().top + drg_h - event.pageY/zoom,
pos_x = $(event.target).offset().left + drg_w - event.pageX/zoom;
drgObj = event.target;
hitObj = null;
$(drgObj).css('z-index', 1000).addClass('dragging');
这里需要注意几点:
- 需要取得当前页面zoom的比率,不然会出现移动错位的现象(跟不上拖动的节奏),如果没有缩放可以设置为1或者不需要改参数。
- 备份当前元素的z-index,用于还原
- 取得要拖动组件的大小
- 以当前点击位置记录组件的开始偏移(相对于页面的)
- 保存拖动对象的索引(拖动过程中需要使用,后面详细解释)
- 把元素置顶,添加拖动样式(比如加边框,3d效果等)
拖动过程中就是修改组件的偏移位置,需要注意的是,拖动过程中,鼠标与拖动的组件会有速度上的差别,尤其是拖动速度比较快时,这个时候,前面保存的拖动对象就可以起作用了。
if (drgObj == null) return;
$(drgObj).offset({
top:event.pageY/zoom + pos_y - drg_h,
left:event.pageX/zoom + pos_x - drg_w
});
在移动事件中,我们修改拖动对象的偏移位置,达到拖动的效果。
如果拖动的过程中需要检测是否命中目标对象(拖动的目的),我们需要检查当前位置是否落在目标对象的范围内,使用如下代码:
function hitObject(x, y, dest){
var dl = $(dest).offset().left;
dt = $(dest).offset().top;
var dh = $(dest).outerHeight(),
dw = $(dest).outerWidth();
if (dl-10 < x && x < dl+dw+10 && dt-10 < y && y < dt+dh+10){
return true;
}
return false;
}
hitObject需要三个参数,x,y为页面坐标,dest为检查的目标组件,比如,”.quan1”就是具有quan1的类对象,最好使用id访问,确保对象唯一:
if (hitObject(event.pageX/zoom, event.pageY/zoom, ".quan1")) {
//...
}
鼠标松开(离开触摸屏)时结束拖动,结束拖动一般需要修改目标对象的样式,表明选中,也可以定位拖动对象,或者把拖动对象还原到原来的位置。还原位置如果是通过修改偏移总有点问题,所以,笔者的做法就是取消拖动添加的样式:
$("#answer1, #answer2, #answer3").css("top", "").css("left", "").css("position", "");
通过清楚top,left和position样式就可以了,由于jQuery添加的样式是直接添加到元素上面的,取消掉后,不影响原来通过class添加的样式。
以上就是通过jQuery实现元素拖动的过程和注意事项,希望读者可以收获自己的灵感。本文使用TouchSwipe组件的swipeStatus中phase参数检查拖动的状态的:
swipeStatus : function(event, phase, direction, distance, duration, fingerCount, fingerData ){
if (phase == "start"){
}else if (phase == "move"){
}else if (phase == "end"){
}
},