JS案例 - 基於vue的移動端長按手勢

來源:互聯網
上載者:User

標籤:事業   自訂事件   預設   分享圖片   can   val   一個   結束   get   

================================慣例碎碎念前言================================

當時首先想到要做長按事件的時候,我想到的是vue內部的自訂指令,畢竟官網裡邊有這麼一句描述:

有的情況下,你仍然需要對普通 DOM 元素進行底層操作,這時候就會用到自訂指令

但是項目用在app中,因為另一個未知原因的bug,自訂事件躺槍(至今死不瞑目)。長按事件被我改成了在初始化時,就直接綁定到需要他的dom上。

 

 ================================正經文================================ 

綁定的命令寫在mounted鉤子裡,這是因為在created內部我也找不到dom,而在mounted階段,所有的dom結構和資料都被展示到頁面當中,

詳情可以參見“vue生命週期強刷”:https://www.cnblogs.com/padding1015/p/9159381.html

 所以,下邊的代碼經過不斷的輪迴,最終是寫在mounted裡邊的

let oDiv = document.getElementById(‘canvas‘);

// 因為長按事件要加在div#canvas上的,如果事件是任何地方的話,就是document

1 oDiv.addEventListener("touchstart", function(e) {}, false);2 3 oDiv.addEventListener("touchmove", function(e) {}, false);4 5 oDiv.addEventListener("touchend", function(e) {}, false);

至於,三個綁定事件的回調裡再寫什麼,就不太關vue的事了(dui,就是這麼草率)。 

 

 

在公布最終的成型代碼之前,容我先補一波關於事件的”兵”。

主要兵線呢有三條:

 

中路:dom2級事件處理常式

上路:事件流

下路:觸摸事件

 

所需事件知識點分布如: 

 

(查看大圖:右鍵新標籤中開啟)掌握了上邊的知識點後,就是在長按功能裡邊的應用了。

 

別急~

長按功能原理分析一波:

所謂的長按其實就是手指按下去,不移動,超過一定時間才把手指拿開的一個過程(我說的好有道理哈哈哈。然後聽到一片同一個聲音:廢話!!)。

而在這個過程中,正好是觸摸的三個事件。

監聽手指按下去後是否有移動,就該touches上場了,監聽他的clientX,clientY只要沒變就是沒移動。

並且在這個過程中,還會不時地有地方的英雄冒出來幹擾我們補兵。那就是一個手機內建的效果了:

  長按時,在移動端觸摸文字,(至少ios裡)會出現選擇文字等幹擾我們的真正功能,用了preventDefault()這個屬性後就沒有了。

 

 

紙上談兵是沒用的額,直接上長按功能代碼

為了不必要的麻煩(其實就是我懶得寫),把多餘的其他代碼刪掉了,所以不要驚訝export default裡邊為什麼只有mounted。

<script>  let x = 0,      y = 0,      z = 0,      timer1 = null;  export default {    mounted(){      let oDiv = document.getElementById(‘canvas‘);      oDiv.addEventListener("touchstart", function(e) {          if (e.preventDefault) e.preventDefault();          else e.returnValue = false;          if (e.touches.length > 1) {            return false;          }          z = 0;          timer1 = setTimeout(function() {            z = 1;          }, 500);          x = e.touches[0].clientX;          y = e.touches[0].clientY;      }, false);      oDiv.addEventListener("touchmove", function(e) {          if (e.preventDefault) e.preventDefault();          else e.returnValue = false;          if (x != e.touches[0].clientX || y != e.touches[0].clientY) {            clearTimeout(timer1);            return false;          }      }, false);      oDiv.addEventListener("touchend", function(e) {        if (e.preventDefault) e.preventDefault();        else e.returnValue = false;        if (z != 1) {          clearTimeout(timer1);          x = 0;          y = 0;          return false;        } else if(z=1){          x = 0;          y = 0;          z = 0;          /* 到這裡已確定觸發了長按事件,接下來執行長按後要做的其他事情 */        }      }, false);    }  }</script>

哎呀,我怎麼可能直接甩了代碼扭頭就走呢!接下來請看~

 

 

講解版本的代碼

<script>  let x = 0,//用於記錄clientX      y = 0,//用於記錄clientX      z = 0,//用於判斷,是否是已按住並超過了設定時間。      timer1 = null;//用於定時器  export default {    mounted(){      let oDiv = document.getElementById(‘canvas‘);      // 因為長按事件要加在div#canvas上的,如果事件是任何地方的話,就是document      /* 添加touchstart,手指觸摸事件 */      oDiv.addEventListener("touchstart", function(e) {          /* 阻止預設事件,其實這裡ie的相容寫法returnValue沒必要*/          if (e.preventDefault) e.preventDefault();          else e.returnValue = false;          /* 移動時觸發touchmove導致多個touches對象,所以可以直接跳出*/          if (e.touches.length > 1) {            return false;          }          /* 這裡有曆史淵源的,是第二次點擊的時候,把z的值還原。*/          z = 0;          /* 手指一旦觸控螢幕幕,就開啟一個倒計時定時器timer1 */          timer1 = setTimeout(function() {            z = 1; // 如果倒計時結束還沒有清楚定時器的話,就把z賦值為1,這樣,當判斷z=1就說明按住螢幕的時間達到了開發人員設定的長按時間。也就是滿足了長按事件          }, 500);          /* 手指一旦觸控螢幕幕,要立即做的第二件事:記錄觸摸時的點的位置,並存在x,y兩個變數裡*/          x = e.touches[0].clientX;          y = e.touches[0].clientY;      }, false);      /* 綁定第二個事件touchmove,手指在螢幕上連續滑動時連續地觸發*/      oDiv.addEventListener("touchmove", function(e) {          if (e.preventDefault) e.preventDefault();          else e.returnValue = false;          /*判斷,因為每次手指移動會連續觸發touchmove,也就會不停的往event事件對象裡邊添加“跟蹤觸摸屬性touches”*/          //這個屬性是一個數組,每次新添加的都會在最前邊。所以每次擷取數組裡邊的第一個對象對應的clientX和clientY,就是即時的移動點的位置          //找這個點的作用,就是為了監聽使用者,是否按住還移動了。如果移動了,那不能算長按事件(不過這個也看產品需求,如果按住也要觸發長按規定那個邏輯的話,這不要判斷)          if (x != e.touches[0].clientX || y != e.touches[0].clientY) {            // 具體的判斷方法,還記得touchstar那裡已經記錄了‘起跑點‘了,只要和x,y的值進行比較,與兩個的值有任意一個不等,就是移動了。            // 那麼移動的話,先要清除事先埋伏的定時器timer1.要不然,雖然不是長按事件但是倒計時還在進行中。            clearTimeout(timer1);            return false;//除掉‘後患‘後,安心的結束本次使用者的觸摸事件監聽。          }      }, false);      /* 添加第三個觸摸事件touchend,這個事件的情境就是使用者手指從螢幕拿開時觸發*/      oDiv.addEventListener("touchend", function(e) {        if (e.preventDefault) e.preventDefault();        else e.returnValue = false;        /* 上文已經介紹,當使用者拿開的時候,只要判斷使用者從點擊到拿開的時間。而記錄時間長度比較麻煩,所以當時用了定時器,設定了一個我們想要的時間,時間到了就改變一個狀態值z,所以這裡我們只要判斷z是否被改變即可*/        if (z != 1) {          /* 如果使用者手指頭拿開的時候,z還是0,即不等於1,說明定時器還沒被觸發,也就說明沒有達到長按的時間,那麼不用期待了,同touchmove壽終正寢時要做的一樣,清除定時器即可。*/          clearTimeout(timer1);          /* 但是,touchend和touchmove還有一點不一樣的,touchend是end(廢話),touchmove不管move多少次,最終手指總要從螢幕拿開的,這就是他的關鍵點。而拿開就是結束,結束,是整個這次觸摸生命過程的結束。*/          /* 所以,end還要做的事是初始化,是還原。他需要把x,y的值歸為原始。以為了下次再次觸發touchstart時做準備。好感人的故事。*/          x = 0;          y = 0;          return false;//然後安心的“死去”。        } else if(z=1){          /* 如果,觸發了長按事件,終於觸發了長按事件!*/          /* 他還是不能得意忘形,在大展宏圖之前,還是要做點準備,打掃一下戰場,將各個變數初始化 */          x = 0;          y = 0;          z = 0;          /* 然後,他才能開心的做自己計劃已久的事業:執行長按後要做的其他事情 */          /* 是什麼事情呢? 五點半了,吃飯。*/        }      }, false);    }  }</script>

 奧,對了還有個現象,在於vue中的swiper一同食用時,長按住並且滑動會觸發上/下翻頁。如果touchmove裡邊還要有什麼動作的話,加上swiper體驗很不好。

 

 

2018-07-07  17:35:31

JS案例 - 基於vue的移動端長按手勢

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.