拖拽原理:
● 当鼠标在盒子上按下的时候,我们开始拖拽
◆ 记录鼠标按下的位置;
◆ 元素当前位置(左上角)
◆ 给元素绑定onmousemove和onmouseup事件
● 当鼠标移动的时候,计算盒子的最新位置(左上角位置)
◆ 考虑边界值问题
● 当鼠标抬起的时候说明拖拽结束,把onmousemove和onmouseup方法移除
注意:鼠标焦点丢失问题
● 鼠标焦点丢失:当鼠标移动过快的时候,鼠标会脱离盒子,导致盒子的mouseup和mousemove事件都移除不掉
◆ 在ie和ff中,用一个方法(setCapture()和releaseCapture())把盒子和鼠标绑定在一起即可
◆ 但是这个方法在chrome下不兼容:解决:我们把mousemove/mouseup绑定给document,此时出现新的问题,事件绑定给document后this指向出问题,要用call重新指向
1.鼠标拖拽
例1:拖拽
var box = document.getElementById("box");
box.style.top = ((document.documentElement.clientHeight || document.body.clientHeight) - box.offsetHeight)/2 +"px";
box.style.left = ((document.documentElement.clientWidth || document.body.clientWidth)-box.offsetWidth)/2 +"px";
box.onmousedown = down;
function down(e){
e = e || window.event;
// 记录鼠标开始位置
this["strX"] = e.clientX;
this["strY"] = e.clientY;
// 记录元素左上角位置
this["strL"] = parseFloat(this.style.left);
this["strT"] = parseFloat(this.style.top);
// 给元素绑定移动和抬起事件
this.onmousemove = move;
this.onmouseup = up;
}
function move(e){
e = e || window.event;
// 当前元素的位置
var curL = (e.clientX - this["strX"]) + this["strL"];
var curT = (e.clientY - this["strY"]) + this["strT"];
// 边界判断
var minL = 0,minT = 0,
maxL = (document.documentElement.clientWidth || document.body.clientWidth)- this.offsetWidth,
maxT = (document.documentElement.clientHeight ||document.body.clientHeight) - this.offsetHeight;
curL = curL < minL ? minL : (curL > maxL ? maxL : curL);
curT = curT < minT ? minT : (curT > maxT ? maxT : curT);
this.style.left = curL + "px";
this.style.top = curT + "px";
}
function up(e){
this.onmousemove = null;
this.onmouseup = null;
}
例2:优化-解决鼠标焦点丢失问题
var box = document.getElementById("box");
box.style.top = ((document.documentElement.clientHeight || document.body.clientHeight) - box.offsetHeight)/2 +"px";
box.style.left = ((document.documentElement.clientWidth || document.body.clientWidth)-box.offsetWidth)/2 +"px";
box.onmousedown = down;
function down(e){
e = e || window.event;
// 记录鼠标开始位置
this["strX"] = e.clientX;
this["strY"] = e.clientY;
// 记录元素左上角位置
this["strL"] = parseFloat(this.style.left);
this["strT"] = parseFloat(this.style.top);
// 给元素绑定移动和抬起事件
if(this.setCapture){//(ie/ff支持)
this.setCapture();//把当前鼠标和this绑定在一起
this.onmousemove = move;
this.onmouseup = up;
} else {
// 这样绑定的话,move和up中的this都变为了document
// document.onmousemove = move;
// document.onmouseup = up;
var _this = this;
document.onmousemove = function(e){
e = e || window.event;
move.call(_this,e);
}
document.onmouseup = function(e){
e = e || window.event;
up.call(_this,e);
}
}
function move(e){
e = e || window.event;
// 当前元素的位置
var curL = (e.clientX - this["strX"]) + this["strL"];
var curT = (e.clientY - this["strY"]) + this["strT"];
// 边界判断
var minL = 0,minT = 0,
maxL = (document.documentElement.clientWidth || document.body.clientWidth) - this.offsetWidth,
maxT = (document.documentElement.clientHeight || document.body.clientHeight) - this.offsetHeight;
curL = curL < minL ? minL : (curL > maxL ? maxL : curL);
curT = curT < minT ? minT : (curT > maxT ? maxT : curT);
this.style.left = curL + "px";
this.style.top = curT + "px";
}
function up(e){
if(this.releaseCapture){//把当前鼠标和this解绑(ie/ff支持)
this.releaseCapture();
this.onmousemove = null;
this.onmouseup = null;
} else {
document.onmousemove = null;
document.onmouseup = null;
}
}
2.触摸拖拽
在移动端触屏事件有四个
// 手势事件
touchstart //当手指接触屏幕时触发
touchmove //当已经接触屏幕的手指开始移动后触发
touchend //当手指离开屏幕时触发
touchcancel事件
每个触摸事件对象中都包括了touches这个属性,用于描述前位于屏幕上的所有手指的一个列表
e.touches确实能保留所有触发点的事件对象
e.touches.length 的长度是手指的触点的个数
e.traget 获取的是当前的元素对象
touches//是当前屏幕上所有触摸点的列表;
targetTouches //是当前对象上所有触摸点的列表;
changedTouches //是涉及当前事件的触摸点的列表。
注意:
touchend 事件中得到的是一个touches的最终值,也就是delete后的列表,所以获取到的touches.length已经减少了,相当于--touches的处理后结果
touches[0] 并不能获取到当前的指向的手势,因为是一个列表,不能确定是哪个一个引用
例:拖拽实例
var box = document.getElementById("box");
box.style.top = ((document.documentElement.clientHeight || document.body.clientHeight) - box.offsetHeight)/2 +"px";
box.style.left = ((document.documentElement.clientWidth || document.body.clientWidth)-box.offsetWidth)/2 +"px";
box.addEventListener('touchstart',down,false);
box.ontouchstart = touchStart;
function touchStart(e){
e = e || window.event;
if(e.touches.length){
e.preventDefault();//防止滑屏
var touch = e.targetTouches [0];
this["strX"] = touch.pageX;
this["strY"] = touch.pageY;
this["strL"] = parseFloat(this.style.left);
this["strT"] = parseFloat(this.style.top);
this.ontouchmove = touchMove;
this.ontouchend = touchEnd;
}
}
function touchMove(e){
e = e || window.event;
e.preventDefault();
var touch = e.targetTouches [0];
var curL = touch.pageX - this["strX"] + this["strL"];
var curT = touch.pageY - this["strY"] + this["strT"];
var minL = 0,minT = 0,
maxL = (document.documentElement.clientWidth || document.body.clientWidth) - this.offsetWidth,
maxT = (document.documentElement.clientHeight || document.body.clientHeight) - this.offsetHeight;
curL = curL < minL ? minL : (curL > maxL ? maxL : curL);
curT = curT < minT ? minT : (curT > maxT ? maxT : curT);
this.style.left = curL + "px";
this.style.top = curT + "px";
}
function touchEnd(e){
this.ontouchmove = null;
this.ontouchend = null;
}