前段时间,写了一个歌词的文章,想着在文章中插入一个APlayer播放组件,但是插入后,凡是通过本站链接点击进入该文章页面时,音乐播放器无法被创建,需要手动刷新以下文章页面才能创建音乐组件。

以下是相关配置:

ID:halo-plugin-aplayer

描述:集成 APlayer 音乐播放器与 MetingJS 到 Halo 2.0。

作者:Azite

版本:1.1.0

废话不多说直接上解决办法,在全局head或页脚中注入以下代码:

<script>
  document.addEventListener("pjax:complete", function() {
  const aplayerElements = document.querySelectorAll("div[aplayer]");
  for (let i = 0; i < aplayerElements.length; i++) {
    const el = aplayerElements[i];
    new APlayer({
      container: el,
      autoplay: el.getAttribute("autoplay") === "true",
      audio: [
        {
          name: el.getAttribute("name"),
          artist: el.getAttribute("artist"),
          url: el.getAttribute("url"),
          cover: el.getAttribute("cover"),
          lrc: el.getAttribute("lrc"),
        },
      ],
    });
  }
});
</script>

其实真正改动的地方只有addEventListener方法的第一个参数,DOMContentLoaded改为pjax:complete

document.addEventListener("DOMContentLoaded"", function() {});
document.addEventListener("pjax:complete", function() {});

插件源代码的逻辑原本是通过监听DOM内容是否加载完成来初始化音乐播放器的。

然而,在PJAX框架下,页面内容是通过异步加载并替换现有页面的部分,而不是重新加载整个页面。因此,当进入文章首页时,整个DOM已经加载完成,但PJAX尚未完成内容的替换。此时执行new APlayer对文章页是无效的,因为文章页中的带有aplayerdiv还没有被创建,APlayer无法对其进行初始化。

而当我们点击进入带有音乐组件的文章时,由于 PJAX 只替换部分页面内容(通常是某个容器内的内容),不会重新加载整个 HTML 文档,因此不会触发全局的 DOMContentLoaded 事件。

所以,我们需要监听 pjax:complete 事件,这个事件会在 PJAX 完成页面内容的替换后被触发,此时再初始化音乐播放器就能确保音乐播放器能够在正确的页面内容下被创建。