【问题标题】:Toggle <audio> src in react.js在 react.js 中切换 <audio> src
【发布时间】:2020-08-31 18:12:30
【问题描述】:

任何有更多 React.js 时间的人会知道如何创建带有音频标签的音乐播放器吗?我正在重新组装组件,但歌曲的 src 没有改变……只有组件重新加载的第一首歌曲……我开发了这个逻辑,但我不知道它是否是最好的……

export default function Header(){
  const catalog = [
    {
    name: 'michael jackson song',
    url: 'michaeljackson.mp3'
    },
    {
    name: 'madonna',
    url: 'madonna.mp3' },
    { 
    name: 'u2',
    url: 'u2.mp3'
    }
]

  const size = catalog.length;

  const [ index, setIndex ] = useState(0);
  const [ principal, setPrincipal ] = useState(null);
  const audioRef = useRef();

 

 useEffect(() => {
  setIndex(Math.floor(Math.random() * size));
},[])

useEffect(() => {
  setPrincipal(catalog[index]);
},[index]);

useEffect(()=>{
  if(index !== null ){
  audioRef.current.addEventListener('ended', () => {
      setIndex( prev => prev + 1 === size - 1 ? prev + 1 : Math.floor(Math.random() * size))})
  }
  },[])


  function handleBack(){
    if( index === 0) {
      setIndex(Math.floor(Math.random() * size))
    } else {
      setIndex( prev => prev - 1);
    }
  }

  function handleNext(){
      setIndex( prev => prev + 1 === size - 1 ? prev + 1 : Math.floor(Math.random() * size))
  }

  return (
    <>
         { principal ? 
         <>
             <div>
                <button onClick={() => handleBack()}> back </button>
                <p>{principal.name}</p>
                <button onClick={() => handleNext()}> next </button>
             </div>
             <audio ref={audioRef} controls>
                <source src={principal.url}/> 
             </audio>
         </>
         : null }
  </> )
}
       

如果有人想测试它,我在 S3 上放了这两条轨道。

https://aleatorio.s3.amazonaws.com/slowdown.mp3

https://atracks.s3.amazonaws.com/Example+-+All+Night+(OUT+NOW).mp3

【问题讨论】:

  • 确保您接受答案,因为它对您有用!

标签: reactjs


【解决方案1】:

问题

问题似乎出在您的自定义 addEventListener 上;因为它只被调用一次,如果源发生变化,监听器处理程序永远不会更新元素

解决方案

在这种情况下,我强烈建议使用 react 方式,直接将函数绑定到元素,而不是尝试手动设置事件监听器。

const domContainer = document.querySelector('#app');
const { useState, useEffect } = React;
const songs = ['https://atracks.s3.amazonaws.com/Example+-+All+Night+(OUT+NOW).mp3', 'https://aleatorio.s3.amazonaws.com/slowdown.mp3'];


function App({ songs = [] }) {
  const [activeSong, setActiveSong] = useState(songs.findIndex(() => true));
  
  const nextSong = () => {
    if (activeSong === songs.length - 1) {
      setActiveSong(0);
    } else {
      setActiveSong(activeSong + 1);
    }
  };
  
  const prevSong = () => {
    if (activeSong === 0) {
      setActiveSong(songs.length - 1);
    } else {
      setActiveSong(activeSong - 1);
    }
  };
  
  
  return (
    <div>
      {activeSong !== -1 && (
        <div>
          <div>
            Source: {songs[activeSong]}
          </div>
          <div>
            <button onClick={prevSong}>prev</button>
            <button onClick={nextSong}>next</button>
          </div>
          <audio controls onEnded={nextSong} src={songs[activeSong]}>
            Your browser does not support the
            <code>audio</code> element.
          </audio>
        </div>
      )}
    </div>
  );
}


ReactDOM.render(<App songs={songs} />, domContainer);
audio {
  margin-top: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

【讨论】:

  • 酷,德里克震撼!!!你有比特币钱包吗?让我给你一些钱
  • @Gabriel - 我没有;但如果你仍然觉得慷慨,你可以随时向任何开源项目捐款!
  • 如果它对你有用,请确保你接受我的回答
  • 你是个好人,德里克!只是一个问题,我将“play()”函数放在哪里,以便在用户与 DOM 交互并且上一首歌曲结束后自动播放?
  • 忘了!只需放入已经有效的自动播放。当它不接触 DOM 时它不起作用,但如果用户点击某些东西,它就已经起作用了!谢谢德里克
猜你喜欢
  • 2016-03-09
  • 2020-04-11
  • 1970-01-01
  • 2017-03-12
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 2011-06-08
  • 2017-06-06
相关资源
最近更新 更多