手機(jī)自定義事件
手機(jī)常用的觸屏事件只有touchstart,touchmove,touchend,其它需要常用的就需要自己封裝
常用事件
使用時調(diào)用的方法,用的是對象的方法巾乳,就不需要在傳參方法時,需要注意先后順序了
funciton touchEvent(init){
var el = init.el;
var isTap = true; //是否發(fā)生點擊(在按下和抬起之間沒有發(fā)生過移動,就是點擊)
var isDblTap = false;//默認(rèn)不是雙擊
var lastPoint = {}; //記錄最后次手指所在位置
var startPoint = {};//記錄touchstart按下時的手指所在位置
var dbTimer = 0;//定義是否是雙擊時間
var longTapTimer = 0;//定義是否是長按時間
el.addEventListener('touchstart',function(e){
lastPoint = {
x: Math.round(e.changedTouches[0].clientX) //event對象獲取到當(dāng)前手指位置
y: Math.round(e.changedTouches[0].clientY)
};
startPoint = {
x: Math.round(e.changedTouches[0].clientX)
y: Math.round(e.changedTouches[0].clientY)
};
longTapTimer = setTimeout(function(){
init.longTap&&init.longTap.call(el,e);
},750)
//定義超過750ms悲关,并且長按函數(shù)存在就執(zhí)行長按函數(shù)
});
/* 安卓下,在touchstart時娄柳,觸發(fā)面積過大時很容易一塊觸發(fā)move */
el.addEventListener('touchmove',function(e){
//獲取移動過程的手指位置
var nowPoint = {
x: Math.round(e.changedTouches[0].clientX)
y: Math.round(e.changedTouches[0].clientY)
}
if(nowPoint.x == lastPoint.x&&nowPoint.y == lastPoint.y){
return; //手指沒有移動就return寓辱,不執(zhí)行操作
}
if(Math.abs(nowPoint.x - startPoint.x) > 5
&&Math.abs(nowPoint.y - startPoint.y)>5)){
clearTimeout(longTapTimer);
}
//如果移動的距離超過5,就判斷不是長按了赤拒,關(guān)閉長按的定時器
lastPoint = {x: nowPoint.x, y: nowPoint.y}
//最后一次點擊位置就變成最后一次移動的手指位置
});
el.addEventListener('touchend',function(e){
//抬起的手指位置
var nowPoint = {
x: Math.round(e.changedTouches[0].clientX),
y: Math.round(e.changedTouches[0].clientY)
}
if(Math.abs(nowPoint.x - startPoint.x)<5
&&Math.abs(nowPoint.y - startPoint.y)<5){
isTap = true;
} else {
isTap = false;
}
isTap&&init.tap&&init.tap.call(el,e)
//判斷抬起和按下的距離小于5秫筏,并且tap事件存在,執(zhí)行tap事件
//*判斷用戶是否執(zhí)行雙擊操作
if(isTap){
if(isDblTap){
clearTimeout(dbTimer);
init.doubleTap&&init.doubleTap.call(el,e);
isDblTap = false;
} else {
isDblTap = true;
dbTimer = setTimeout(function(){
isDblTap = false;
init.doubleTap&&init.doubleTap.call(el,e);
//init.singleTap&&init.singleTap.call(el,e);
},300)
}
}
//點擊后為true,但是isDblTap默認(rèn)為false走else挎挖,在dbTimer 300ms之類再次點擊就是这敬,執(zhí)行雙擊doubleTap事件,*因為是雙擊會也觸發(fā)點擊的事件蕉朵,如果要不沖突就改為執(zhí)行singleTap單擊
if(getDis(nowPoint,startPoint) >= 20){
//在屏幕中滑動了
init.swipe&&init.swipe.call(el,e);;
}
if(nowPoint.x - startPoint.x >= 20){
init.swipeRight&&init.swipeRight.call(el,e);;
} else if(nowPoint.x - startPoint.x <= -20){
init.swipeLeft&&init.swipeLeft.call(el,e);;
}
if(nowPoint.y - startPoint.y >= 20){
init.swipeDown&&init.swipeDown.call(el,e);;
} else if(nowPoint.y - startPoint.y <= -20){
init.swipeUp&&init.swipeUp.call(el,e);
}
//根據(jù)滑動的距離和差值來判斷是往那邊滑動
isTap = true;
});
}
init: {
el: el,//要添加事件的元素
tap: fn,//點擊
longTap: fn,//長按
singleTap: fn,//單擊
doubleTap: fn,//雙擊
swipe: fn,//滑動
swipeLeft: fn,//向左滑動
swipeRight: fn,//向右滑動
swipeUp: fn,//向上滑動
swipeDown: fn//向下滑動
}
縮放崔涂,旋轉(zhuǎn)
gesture事件:
- gesturestart 當(dāng)前事件觸發(fā)時,屏幕上有兩根或者兩根以上的手指
- gesturechange 觸發(fā)了gesturestart 之后始衅, 手指坐標(biāo)發(fā)生變化
- gestureend 觸發(fā)了gesturestart 之后冷蚂,手指抬起
安卓手機(jī)下沒有g(shù)esture事件(手勢事件),就需要自己封裝gesture事件
function gesture(init){
var el = init.el;
var isGesture = false;
var startDis = 0;
var startDeg = 0;
el.addEventListener('touchstart',function(e){
if(e.touches.length >= 2){
isGesture = true;
startDis = getDis(e.touches[0],e.touches[1]);
startDeg = getDeg(e.touches[0],e.touches[1]);
init.start&&init.start.call(el,e);
}
});
el.addEventListener('touchmove',function(e){
if(isGesture&&e.touches.length >= 2){
isGesture = true;
var nowDis = getDis(e.touches[0],e.touches[1]);
var nowDeg = getDeg(e.touches[0],e.touches[1]);
e.scale = nowDis/startDis; //2指的距離差值比就是縮放的比例
e.rotation = nowDeg - startDeg; //2指的角度差指變化就是旋轉(zhuǎn)的角度
init.change&&init.change.call(el,e);
}
});
el.addEventListener('touchend',function(e){
if(isGesture){
init.end&&init.end.call(el,e);
}
isGesture = false;
})
function getDis(Point,Point2){ //獲取2指之間的距離
return Math.sqrt((Point.pageX - Point2.pageX)*(Point.pageX - Point2.pageX) + (Point.pageY - Point2.pageY)*(Point.pageY - Point2.pageY));
}
function getDeg(Point,Point2){ //
var y = Point.pageY - Point2.pageY;
var x = Point.pageX - Point2.pageX;
return Math.atan2(y,x)/Math.PI*180;
//函數(shù)atan2(y,x)中參數(shù)的順序是倒置的汛闸,atan2(y,x)計算相當(dāng)于點(x,y)的角度值
}
}
由于css設(shè)置的transform的值獲取到的是矩陣蝙茶,不能反向推出來獲取到具體的數(shù)值,必須先把transform設(shè)置到行間樣式上诸老,進(jìn)行獲取
function css(el,attr,val){
var transform = ['rotate','rotateX','rotateY','rotateZ','scale','scaleX','scaleY','skewX','skewY','translateX','translateY','translateZ'];
for(var i = 0; i < transform.length; i++){
if(attr == transform[i]){
return setTransform(el,attr,val);
}
}
};
function setTransform(el,attr,val){
if(!el.transform){
el.transform = {};
//如果元素沒有這個自定義屬性我們就創(chuàng)建一下尸闸,格式是個對象
}
if(typeof val == "undefined"){
return el.transform[attr];
} else {
el.transform[attr] = val;
var value = "";
for(var s in el.transform){
//console.log(s,el.transform[s]);
switch(s){
case "rotate":
case "rotateX":
case "rotateY":
case "rotateZ":
case "skewX":
case "skewY":
value += (s+"("+el.transform[s]+"deg) ");
break;
case "translateX":
case "translateY":
case "translateZ":
value += (s+"("+el.transform[s]+"px) ");
break;
case "scale":
case "scaleX":
case "scaleY":
value += (s+"("+el.transform[s]+") ");
break;
}
}
el.style.WebkitTransform = value;
el.style.MozTransform = value;
el.style.msTransform = value;
el.style.transform = value;
}
}
//這個方法,3個參數(shù)就是設(shè)置樣式,2個參數(shù)就是獲取樣式
使用封裝的getsture()方法
/*
init: {
el: 元素吮廉,
start: fn,
change: fn,
end: fn
}
*/
function(){
var box = document.querySelector("#box");
var startDeg = 0; //定義一個初始角度苞尝;
var startScale = 0;//定義個一個初始縮放比例;
css(box,"scale",100)
css(box."rotate",0);
//調(diào)用上面的css方法宦芦,設(shè)置下行間樣式scale,rotate屬性;
//*使用gesture方法
gesture({
el: box, //需要動畫的元素
start: function(e){ //start就是按下touchstart的執(zhí)行的宙址,獲取到初始的位置和元素的樣式
startScale = css(box,"scale") //css這個方法,3個參數(shù)就是設(shè)置樣式调卑,2個參數(shù)就是獲取樣式
startDeg = css(box,"rotate");
}抡砂,
change: function(e){ //移動的時候 就可以開始發(fā)生變化了
css(this,"scale",(e.scale * startScale); //移動產(chǎn)生的縮放比例*默認(rèn)的縮放當(dāng)前比例
css(box,"rotate",e.rotation + startDeg); //移動產(chǎn)生的角度變化加上本身的元素的當(dāng)前角度
}
end: function(e){
//手指抬起要執(zhí)行的方法,可以根據(jù)自己的要求去添加包括以上的start和change
}
})
}