You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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>

代码说明:

  1. 数组重构:把每个文本组和对应的音频URL封装成对象,这样后续新增文本组和音频时,直接在数组里加对象就行,不用改其他逻辑,扩展性更好。
  2. 音频加载逻辑封装:单独写了loadCurrentAudio函数,负责停止旧音频、加载当前选中项的音频,代码更集中。
  3. 切换逻辑简化:previous和next函数现在只需要处理索引切换、渲染文本,然后调用loadCurrentAudio就行,不用一堆if判断索引。
  4. 播放控制优化:把播放、暂停、重置的事件监听单独绑定,避免每次加载音频都重复绑定,减少内存占用。

内容的提问来源于stack exchange,提问作者JaDoLo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:16:36