在浏览个人博客时,背景音乐能带来更好的沉浸感。但传统的多页面博客每次跳转都会刷新整个页面,导致音乐中断。本文将详细介绍如何在 Hexo 博客中实现一个黑胶风格的音乐播放器,并利用 PJAX 技术实现全站无刷新跳转,让音乐持久播放。

一、界面设计:复古黑胶风格
我们的目标是设计一个带有旋转动画和唱臂效果的迷你播放器,放置在侧边栏导航下方。
1. HTML 结构
在侧边栏模板(如 layout/partials/sidebar.ejs)中添加如下结构:
<% if (theme.music && theme.music.enable) { %> <div class="music-player-wrapper"> <div class="vinyl-record-container" id="vinyl-container"> <div class="vinyl-record" id="vinyl-record"> <div class="vinyl-grooves"></div> <div class="vinyl-label"> <div class="vinyl-hole"></div> </div> </div> <div class="tonearm" id="tonearm"></div> </div> <div class="music-controls-mini" id="music-controls"> <i class="fas fa-step-backward" id="prev-btn"></i> <i class="fas fa-play" id="play-btn"></i> <i class="fas fa-step-forward" id="next-btn"></i> </div> <audio id="bg-music" preload="none"></audio> </div> <% } %>
|
2. CSS 样式与动画
使用 CSS3 实现唱片旋转和唱臂移动的拟物效果。核心代码如下(Stylus):
.vinyl-record-container position relative width 120px height 120px transition all 0.3s ease
.vinyl-record.spinning animation spin 4s linear infinite
@keyframes spin from { transform: rotate(0deg) } to { transform: rotate(360deg) }
.tonearm position absolute top -10px right -5px width 8px height 90px background #ccc transform-origin 4px 4px transform rotate(-35deg) // 初始位置:抬起 transition transform 0.5s cubic-bezier(0.4, 0, 0.2, 1)
.vinyl-record-container.playing .tonearm transform rotate(-5deg)
|
二、播放逻辑实现
通过 JavaScript 控制 audio 元素和 UI 状态的同步。
document.addEventListener('DOMContentLoaded', function() { const audio = document.getElementById('bg-music'); const playlist = <%- JSON.stringify(theme.music.songs) %>; let isPlaying = false;
function togglePlay() { if (audio.paused) { audio.play().then(() => { isPlaying = true; document.getElementById('vinyl-record').classList.add('spinning'); document.getElementById('vinyl-container').classList.add('playing'); playBtn.classList.replace('fa-play', 'fa-pause'); }); } else { audio.pause(); isPlaying = false; document.getElementById('vinyl-record').classList.remove('spinning'); document.getElementById('vinyl-container').classList.remove('playing'); playBtn.classList.replace('fa-pause', 'fa-play'); } } });
|
三、核心难点:利用 PJAX 实现不中断播放
要让音乐在页面跳转时继续播放,我们需要使用 PJAX (PushState + AJAX)。它的原理是:拦截链接点击,通过 AJAX 请求新页面内容,只替换页面的主体部分(Main Content),而保留侧边栏(播放器所在位置)和页脚等不常变动的区域。
1. 引入依赖
在 layout.ejs 中引入 jQuery 和 jquery-pjax:
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>
|
2. 初始化 PJAX
配置 PJAX 接管所有站内链接,并指定更新容器为 .main-content:
$(document).ready(function() { $(document).pjax('a[href^="<%= config.root %>"]', '.main-content', { fragment: '.main-content', timeout: 8000 });
$(document).on('pjax:complete', function() { if (window.Prism) window.Prism.highlightAll(); $.getScript("https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"); }); });
|
3. 遇到的坑与解决方案
问题一:评论区不加载
Gitalk 等评论插件通常在页面加载时初始化。PJAX 替换内容后,旧的脚本不再执行。
解决:将评论脚本放在 .main-content 容器内部,或者在 pjax:complete 回调中手动重新实例化评论插件。
问题二:第三方 JS 失效
如不蒜子统计、数学公式渲染等,都需要在 pjax:complete 中显式重新加载或调用其刷新方法。
四、总结
通过以上步骤,我们不仅给博客添加了一个高颜值的黑胶播放器,更通过 PJAX 技术极大地提升了用户体验。现在,用户可以在浏览文章、查看归档的同时,享受不间断的背景音乐陪伴。
这种“单页应用”般的体验,是现代静态博客优化的重要方向之一。
文章作者:阿文
版权声明:本博客所有文章除特别声明外,均采用
CC BY-NC-SA 4.0 许可协议。转载请注明来自
阿文的博客!