TouchEvent實現前端錄音打分功能

cayley的程式設計之路發表於2018-04-12

由於本人從事的是線上英語教育工作,所以會做很多學習互動的功能,在英語學習過程中,跟讀這種練習口語的功能肯定屬於必須的互動,今天就總結一下實現這個跟讀打分的功能,以及涉及的知識點。

功能展示

TouchEvent實現前端錄音打分功能

預設初始狀態

TouchEvent實現前端錄音打分功能

按下錄音的狀態

TouchEvent實現前端錄音打分功能

打分中的狀態

TouchEvent實現前端錄音打分功能

打分完畢擁有自己讀音和成績狀態,可重錄

涉及知識點

  • TouchEvent事件 (touchstart, touchend, touchcancel)的理解和使用
  • readStatus 狀態的處理 (default預設, recording錄音中, waitingScore等待打分, scoreComplete打分完畢同default可忽略)
  • 對應的處理方法

Touch事件講解

TouchEvent 是一類描述手指在觸控平面(觸控式螢幕、觸控板等)的狀態變化的事件。這類事件用於描述一個或多個觸點,使開發者可以檢測觸點的移動,觸點的增加和減少,等等。 (from MDN)

  • touchstart 當使用者在觸控平面上放置了一個觸點時觸發。事件的目標 element 將是觸點位置上的那個目標 element

  • touchend 當一個觸點被使用者從觸控平面上移除(當使用者將一個手指離開觸控平面)時觸發。當觸點移出觸控平面的邊界時也將觸發。例如使用者將手指劃出螢幕邊緣。事件的目標 element 和這個 touchend 事件對應的 touchstart 事件的目標 element 相同,哪怕 touchend 事件觸發時,觸點已經移出了該 element 。

  • touchmove 當使用者在觸控平面上移動觸點時觸發。事件的目標 element 和這個 touchmove 事件對應的 touchstart 事件的目標 element 相同,哪怕當 touchmove 事件觸發時,觸點已經移出了該 element 。當觸點的半徑、旋轉角度以及壓力大小發生變化時,也將觸發此事件。

  • touchcancel 當觸點由於某些原因被中斷時觸發。有幾種可能的原因如下(具體的原因根據不同的裝置和瀏覽器有所不同):

  1. 於某個事件取消了觸控:例如觸控過程被一個模態的彈出框打斷。
  2. 觸點離開了文件視窗,而進入了瀏覽器的介面元素、外掛或者其他外部內容區域。
  3. 當使用者產生的觸點個數超過了裝置支援的個數,從而導致 TouchList 中最早的 Touch 物件被取消。

功能分析和講解

以上幾個API是實現模擬錄音功能的重要方法,我們在程式碼中只需要設定一個Element上繫結這些方法,然後完善具體的功能即可,值得注意的是,由於做移動端開發,在本地開發的時候無法在PC上模擬出每個狀態下的效果,所以可以給Element綁上相應的滑鼠事件。(此處用到的框架是vue)

<button @touchstart="onStartRecord" @touchend="onStopRecord" @touchmove="onPrevent"
@mousedown="onStartRecord" @mouseup="onStopRecord"></button>
複製程式碼

注意:在很多情況下,觸控和滑鼠事件都會被髮送,所以應在對應的方法裡呼叫$preventDefault()以保持傳送滑鼠事件

  • onStartRecord開始錄音功能的方法,具體實現可看註釋
onStartRecord: function (event) {
  // 阻止預設事件
   if (event) {
       event.preventDefault();
       event.stopPropagation();
    }
  // 不是可錄音狀態下不處理
   if (this.readStatus != 'default') {
         return;
   }
   console.log('onStartRecord');
   this.readStatus = 'recording';

  //定義錄音的幾個回撥函式根據自己的業務處理
   let scoreCompleteCallback = function (scoreData) {
   }.bind(this);
   let stopRecordCallback = function () {
   }.bind(this);
   let scoreErrorCallback = function (error) {
   }.bind(this);

  //呼叫和原生定義好的方法去錄音打分
 mobile.external.StartRecord({
      stopRecordCallback: stopRecordCallback,
      scoreCompleteCallback: scoreCompleteCallback,
      scoreErrorCallback: scoreErrorCallback
  });

 }
複製程式碼
  • onStopRecord 停止錄音方法
onStopRecord: function (event) {
 if (event) {
       event.preventDefault();
       event.stopPropagation();
 }
 if (this.readStatus != 'default') {
         return;
 }
console.log('onStopRecord');
//呼叫和原生定義好的方法去停止打分
mobile.external.oralStopRecord(this.recordId);
}
複製程式碼
  • onPrevent 阻止預設的行為
onPrevent: function (event) {
// 阻止預設事件
   if (event) {
       event.preventDefault();
       event.stopPropagation();
    }
}
複製程式碼
  • 根據status狀態來更改樣式文案等方法
watch: {
    readStatus: function($newStatus){
      switch ( $newStatus ) {
          //根據case來去做什麼樣式變更之類,此方法靈活使用
      }
    }
}           
複製程式碼

寫在最後的總結

其實這個功能實現起來不困難,只要掌握了具體的API可以很快完成互動的邏輯,難點在於具體業務實施時與殼的方法聯調,各種回掉函式的處理,以及具體裝置上體驗的質量,本文只是提供一個思路,如果你在書寫邏輯時遇到了什麼難點,歡迎評論也許可以幫你解決問題。

Cayley 一個不斷努力學習的女程式設計師

相關文章