如何通过Prev/Next按钮正确加载对应文本与音频文件?
解决方案:绑定文本组与音频URL,简化切换逻辑
我来帮你梳理下这个问题,其实核心是把文本组和对应的音频URL直接绑定起来,这样切换的时候就能精准加载对应的音频了。你的现有代码里用了隐藏的clip元素来触发加载,逻辑有点绕,我们可以简化一下,让代码更清晰易维护:
关键优化点:
- 重构数组结构,把每个文本组和对应的音频URL放在一起,避免分散的判断
- 移除冗余的
clip1/clip2/clip3元素及点击事件,直接在切换时调用音频加载逻辑 - 简化
previous和next函数的判断逻辑,不用一堆if逐个匹配索引 - 切换时自动停止当前播放的音频,避免多个音频同时运行
修改后的完整代码:
<script src="//cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script> <p id="arr1">Test Text</p> <p id="arr2">Test Text</p> <p id="arr3">Test Text</p> <button id="play" class="play">Play</button> <button id="paused" class="paused">Pause</button> <button id="reset" class="reset">Reset</button> <input type="button" id="prev_button" value="<< Prev"> <input type="button" id="next_button" value="Next >>"/> <script> var currentArray = -1; // 重构数组:每个项包含文本组和对应的音频URL var arrays = [ { texts: ["Argument arr1,1", "Argument arr1,2", "Argument arr1,3", "Argument arr1,4"], audioUrl: "https://cdn.rawgit.com/mrdoob/three.js/master/examples/sounds/358232_j_s_song.mp3" }, { texts: ["Argument arr2,1", "Argument arr2,2", "Argument arr2,3", "Argument arr2,4"], audioUrl: "https://cdn.rawgit.com/mrdoob/three.js/master/examples/sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3" }, { texts: ["Argument arr3,1", "Argument arr3,2", "Argument arr3,3", "Argument arr3,4"], audioUrl: "https://cdn.rawgit.com/mrdoob/three.js/master/examples/sounds/358232_j_s_song.mp3" } ]; var listener = new THREE.AudioListener(); var audioLoader = new THREE.AudioLoader(); var sound = null; // 全局保存当前音频实例 var renderArray = function renderArray( ary ) { document.querySelector( '#arr1' ).textContent = ary.texts[ 0 ]; document.querySelector( '#arr2' ).textContent = ary.texts[ 1 ]; document.querySelector( '#arr3' ).textContent = ary.texts[ 2 ]; }; var loadCurrentAudio = function() { // 如果已有音频,先停止并重置 if (sound) { sound.stop(); } const currentItem = arrays[currentArray]; console.log(`\nLoading sound...`); audioLoader.load( currentItem.audioUrl, function( buffer ) { sound = new THREE.PositionalAudio( listener ); sound.setBuffer( buffer ); sound.setRefDistance( 20 ); sound.setLoop(false); sound.setVolume(5); console.log(`\nAudio finished loading!`); // 重置播放按钮状态 document.getElementById('play').disabled = false; document.getElementById('paused').disabled = true; document.getElementById('reset').disabled = true; }); }; var previous = function previous( event ) { currentArray -= 1; if ( currentArray < 0 ) currentArray = arrays.length - 1; renderArray( arrays[ currentArray ] ); loadCurrentAudio(); // 切换后加载对应音频 }; var next = function next( event ) { currentArray += 1; if ( currentArray > arrays.length - 1 ) currentArray = 0; renderArray( arrays[ currentArray ] ); loadCurrentAudio(); // 切换后加载对应音频 }; // 播放控制逻辑 document.querySelector( '#play' ).addEventListener('click', function() { if (!sound) return; console.log( `\nplayClip()` ); this.style.background = "#92ddb8"; document.getElementById('reset').disabled = false; this.disabled = true; document.getElementById('paused').disabled = false; sound.play(); }); document.querySelector( '#reset' ).addEventListener('click', function() { if (!sound) return; console.log( `\nresetClip()` ); document.getElementById('play').style.background = ""; document.getElementById('play').style.color = ""; document.getElementById('play').disabled = false; document.getElementById('paused').disabled = true; sound.stop(); console.clear(); }); document.querySelector( '#paused' ).addEventListener('click', function() { if (!sound) return; console.log( `\npausedClip()` ); document.getElementById('play').style.background = ""; document.getElementById('play').style.color = ""; document.getElementById('play').disabled = false; this.disabled = true; sound.pause(); }); // 绑定切换按钮事件 document.querySelector( '#prev_button' ).addEventListener( 'click', previous ); document.querySelector( '#next_button' ).addEventListener( 'click', next ); // 初始化加载第一个音频 currentArray = 0; renderArray(arrays[0]); loadCurrentAudio(); </script>
代码说明:
- 数组重构:把每个文本组和对应的音频URL封装成对象,这样后续新增文本组和音频时,直接在数组里加对象就行,不用改其他逻辑,扩展性更好。
- 音频加载逻辑封装:单独写了
loadCurrentAudio函数,负责停止旧音频、加载当前选中项的音频,代码更集中。 - 切换逻辑简化:
previous和next函数现在只需要处理索引切换、渲染文本,然后调用loadCurrentAudio就行,不用一堆if判断索引。 - 播放控制优化:把播放、暂停、重置的事件监听单独绑定,避免每次加载音频都重复绑定,减少内存占用。
内容的提问来源于stack exchange,提问作者JaDoLo
相关产品推荐
相关产品推荐

