手機(jī)端封裝一些常用事件

手機(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
    } 
  })
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恬涧,一起剝皮案震驚了整個濱河市注益,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溯捆,老刑警劉巖丑搔,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異提揍,居然都是意外死亡啤月,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門劳跃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谎仲,“玉大人,你說我怎么就攤上這事刨仑≈E担” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵杉武,是天一觀的道長辙诞。 經(jīng)常有香客問我,道長艺智,這世上最難降的妖魔是什么倘要? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮十拣,結(jié)果婚禮上封拧,老公的妹妹穿的比我還像新娘。我一直安慰自己夭问,他們只是感情好泽西,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缰趋,像睡著了一般捧杉。 火紅的嫁衣襯著肌膚如雪陕见。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天味抖,我揣著相機(jī)與錄音评甜,去河邊找鬼。 笑死仔涩,一個胖子當(dāng)著我的面吹牛忍坷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播熔脂,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼佩研,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霞揉?” 一聲冷哼從身側(cè)響起旬薯,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎适秩,沒想到半個月后绊序,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡隶症,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年政模,在試婚紗的時候發(fā)現(xiàn)自己被綠了岗宣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚂会。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖耗式,靈堂內(nèi)的尸體忽然破棺而出胁住,到底是詐尸還是另有隱情,我是刑警寧澤刊咳,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布彪见,位于F島的核電站,受9級特大地震影響娱挨,放射性物質(zhì)發(fā)生泄漏余指。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一跷坝、第九天 我趴在偏房一處隱蔽的房頂上張望酵镜。 院中可真熱鬧,春花似錦柴钻、人聲如沸淮韭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽靠粪。三九已至蜡吧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間占键,已是汗流浹背昔善。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留畔乙,地道東北人耀鸦。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像啸澡,于是被迫代替她去往敵國和親袖订。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容