小程式[InnerAudioContext]重複播放n次音訊

kirian發表於2019-04-28

結果

function loopVoice(srcs,maxtimes) {
  let secondIAC = wx.createInnerAudioContext()
  secondIAC.obeyMuteSwitch = false
  secondIAC.onError(() => {
    showToast({
      icon: 'none',
      title: '載入失敗',
    })
  })
  let times = 0
  secondIAC.src = src[times]
  secondIAC.onPlay(() => {
    times++
  })
  secondIAC.onEnded(() => {
    if (times === maxtimes) {
      secondIAC.destroy()
    }
    secondIAC.src = src[times]
    secondIAC.play()
  })
  secondIAC.play()
}
複製程式碼

起因

今天我在社群發了一個帖子小程式播放同一音訊兩次要怎麼寫?想要跟大家探討一下怎麼寫好這個功能。

由於我對需求的錯誤理解,誤以為要連續播放兩次相同的音訊,我踏上了探索之路。

經過與探索

在寫網頁尾本的過程中,時間監聽是我非常喜歡的一系列介面(誰還沒個特殊癖好呢),原因當然是因為這些事件一旦觸發必有回應,讓人覺得非常給力!

有一位前輩曾經指導過我,小程式裡的種種功能不過是對網頁介面的優化封裝與擴充,往往在Web API中都有對應的功能存在,那麼我們先來了解一下網頁中的監聽事件吧!

學習資料:

同一個 EventTarget 註冊了多個相同的 EventListener,那麼重複的例項會被拋棄。所以這麼做不會使得 EventListener 被呼叫兩次,也不需要用 removeEventListener 手動清除多餘的EventListener ,因為重複的都被自動拋棄了,前提是options中的capture的引數值一致,如果capture的值不一致,此時就算重複定義,也不會被拋棄掉。

// 改變t2的函式
function modifyTextPlus() {
  console.log("plus")
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    console.log('plus +1')
    t2.firstChild.nodeValue = "two";
  } else {
    console.log('plus -1')
    t2.firstChild.nodeValue = "three";
  }
}// 改變t2的函式
function modifyTextMinus() {
  console.log('minus')
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "one") {
    console.log('minus +1')
    t2.firstChild.nodeValue = "two";
  } else {
    console.log('minus -1')
    t2.firstChild.nodeValue = "one";
  }
}

// 為table新增事件監聽器
var el = document.getElementById("outside");
el.addEventListener("click", modifyTextPlus, false);
el.addEventListener("click", modifyTextMinus, false);

複製程式碼

猜猜這段程式碼的執行結果是什麼樣呢?CodePen:點選檢視答案

這裡多說一句,面試的時候大佬對我使用addEventListener提出了質疑,現在已經不記得具體內容了。大概是說使用on監聽的話回撥都會被執行,此處還需更進一步探索!

看完了Web API,我們來看一下小程式的API,此處以InnerAudioContext的介面為例。小程式:API文件

可以看到,InnerAudioContext的介面包含了一些基本的控制功能,此外還有一些看著就成雙成對的功能函式(這年頭程式碼都要喂狗糧),此處以onEnded和offEnded為例,他們分別代表“監聽音訊自然播放至結束的事件”和“取消監聽音訊自然播放至結束的事件”。

一開始呢,我是這樣實現目標功能的:

  innerAudioContext.src = "xxxx"
  innerAudioContext.onEnded(() => {
    innerAudioContext.onPlay(() => {
      innerAudioContext.offEnded()
    })
    innerAudioContext.play() 
  })

  innerAudioContext.play()
複製程式碼

想要用一個已經定義的全域性變數不斷得呼叫play方法來實現多次播放,但是一旦呼叫了offEnded()之後想重新新增onEnded()就不行了,這樣導致了這段程式碼只能一次使用。

小程式的監聽介面與Web API有一點相反,當我新增了多個監聽事件後觸發時它們都會執行回撥。

寫到這裡我的探索也到了終點,因為終於發現是自己理解錯了互動了!

相關文章