• 实现原理

    使用BroadcastChannelAPI可以在同源的条件下创建自定义命名的频道,频道名相同可以相互通信。使用message事件监听,使用postMessage发送信息

  • 项目代码

    • 代码树

      core.js
      index.html
      play.html
    • core.js

      const musicList=[
          {name:'嘉宾',url:'https://cdn-static.xxcheng.cn/static/blog/images/2022/06/15/f54fb5f042ae6fe0bf1a8af731ae0db7.mp3'},
          {name:'嗷呜一口仙贝 - 必杀技',url:'https://cdn-static.xxcheng.cn/static/blog/images/2023/05/08/dc97503c338d3ea64e266425bdf8b54e.mp3'},
          {name:'毛不易 - 入海',url:'https://cdn-static.xxcheng.cn/static/blog/images/2023/05/08/fb41c9001784b0b25c4141f29a7bbf7b.mp3'}
      ]
      
      function createId(name){
          let key=`channel-${name}-id`;
          let id=localStorage.getItem(key);
          if( !id ){
              id=0;
          }
          id++;
          localStorage.setItem(key,id.toString());
          return id;
      }
      
      function sendMsg(channel,msg,type='default'){
          channel.postMessage({
              id:channel.id,
              type,
              msg
          });
      }
      
      function createChannel(name,type='default'){
          const channel= new BroadcastChannel(name);
          channel.id=createId(name);
          channel.listeners=new Set();
          sendMsg(channel,type,'hello');
          window.addEventListener('unload',function(){
              sendMsg(channel,type,'bye');
          });
          channel.addEventListener('message',function(e){
              if( e.data.type==='bye' ){
                  console.log('bye',e.data.id);
                  channel.listeners.delete(e.data.msg+'-'+e.data.id);
              }else if( e.data.type==='hello' ){
                  console.log('hello',e.data.id);
                  channel.listeners.add(e.data.msg+'-'+e.data.id);
                  sendMsg(channel,type,'rehello');
              }else if( e.data.type==='rehello' ){
                  console.log('rehello',e.data.id);
                  channel.listeners.add(e.data.msg+'-'+e.data.id);
              }
          })
          return channel;
      }
    • index.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>首页</title>
      </head>
      <body>
          <script src="./core.js"></script>
          <h3>在线播放音乐</h3>
          <table border="1">
              <thead>
                  <tr>
                      <td>名称</td>
                      <td>播放</td>
                  </tr>
              </thead>
              <tbody id="music-container"></tbody>
          </table>
          <script>
              const musicContainer=document.querySelector('#music-container');
              let html='';
              musicList.forEach((musicItem,index)=>{
                  html+=`<tr>
                      <td>${musicItem.name}</td>
                      <td><button onclick="toPlay('${index}')">播放</button></td>
                  </tr>`;
              })
              musicContainer.innerHTML=html;
              const channel=createChannel('music');
              console.log(channel);
              function toPlay(index){
                  if( channel.listeners.size>0 ){
                      for( let name of channel.listeners ){
                          if( name.indexOf('player')===0 ){
                              console.log('有播放器了~~~');
                              sendMsg(channel,index,'switchSong');
                              return;
                          }
                      }
                  }
                  window.open('./play.html?id='+index);
              }
      
          </script>
      </body>
      </html>
    • play.html

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta http-equiv="X-UA-Compatible" content="IE=edge">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>播放页面</title>
          </head>
          <body>
              <script src="./core.js"></script>
              <audio id="musicEl" controls autoplay></audio>
              <script>
              const url=new URL(location.href);
              const musicId=url.searchParams.get('id');
              const musicEl=document.querySelector('#musicEl');
              if( musicList[musicId] ){
                  musicEl.src=musicList[musicId].url;
                  musicEl.play();
              }
      
              const channel=createChannel('music','player');
              channel.addEventListener('message',e=>{
                  if( e.data.type==='switchSong' ){
                      musicEl.src=musicList[e.data.msg].url;
                  }
              });
          </script>
          </body>
      </html>
  • 实现效果浏览

    点击浏览

  • 参考链接

文章目录