如今不少移動端要求audio播放必需由用戶的事件觸發,不然就劫持。實際應用中常常會出現JS網絡請求經過返回的結果來決定播放什麼音頻,在移動端是不容許的。網絡
當移動須要經過網絡請求回調來播放音頻時,就得作點準備工做,具體代碼以下:app
加載準備處理
ide
/** * 循環處理 * @param {Object} data * @param {Function} callback * @returns {undefined} */ function each(data, callback) { if (typeof data === 'object') { if (data.length) { for (var key = 0; key < data.length; key++) { if (callback(key, data[key]) === false) { break; } } } else { for (var key in data) { if (callback(key, data[key]) === false) { break; } } } } } /** * 播放音頻 * @param {String} name * @returns {undefined} */ function audioPaly(name) { each(name.split(/\s+/), function (_, name) { if (audioPaly.lists[name]) { audioPaly.lists[name].play(); } }); } audioPaly.lists = {}; /** * 就緒音頻處理 * @returns {undefined} */ function audioReady() { var audio; while ((audio = audioReady.lists.pop())) { audio.play(); audio.pause(); //直接暫停,可快速再播放 } } audioReady.lists = []; /** * 加載音頻 * @param {String} path * @param {Function} callback * @returns {undefined} */ function loadAudio(path, callback) { var audio = create('audio', {preload: 'load'}); each({'ogg': 'ogg', 'mp3': 'mpeg', 'wav': 'wav'}, function (name, type) { audio.appendChild(create('source', {src: '/audio/' + path + '.' + name, type: 'audio/' + type})); }); addEvent(audio, 'loadedmetadata', function () { audioPaly.lists[path] = { play: function () {//播放 audio.currentTime = 0; //這個用途不大,兼容處理 if (!audio.ended) { audio.load(); //從新加載,兼容處理,同時也能夠快速開始播放 } audio.play(); } }; audioReady.lists.push(audio); callback && callback(); }); loadAudio.frame.appendChild(audio); } /** * 建立元素 * @param {String} elem * @param {Object} addAttr * @returns {Element} */ function create(elem, addAttr){ var Elem = document.createElement(elem); for(var key in addAttr){ Elem.setAttribute(key, addAttr[key]); } return Elem; } //加載音頻 loadAudio('test');
用戶事件觸發處理事件
//綁定用戶可觸發元素點擊事件 element.addEventListener('click', function(){ audioReady();//音頻觸發就緒處理,用於回調再次播放 //網絡請求代碼 .... //網絡回調器 function (){ audioPaly('test');//播放處理 } .... });
準備的音頻文件(爲何準備多個就很少說了,具體看面向的終端支持音頻格式來定)element
/audio/test.mp3it
/audio/test.oggio
/audio/test.wavfunction
這段代碼並不複雜,只是利用了移動端限制中的一點點許可,當在用戶觸發事件中播放了,那麼在後續的操做的就能夠再次播放。class
只要咱們在用戶觸發後播放音頻並及時暫停或靜音就能夠不被聽到音頻,而後在網絡請求回調中再次操做播放便可實現,動態播放。
test