Aplayer+MetingJS+Pjax=网“页”云音乐
关于如何给网页引入一个不会中断的质朴无华播放器这件事
Aplayer的引用
注:我使用的主题是Noemoe,全改动都在layout.ejs中配置
前言
现在网页中引用音乐播放器的方式总共就两种
- 音乐平台提供的iframe插件,以网易云为例子:
效果预览:
- 使用网页插件,以Aplayer+MetingJS为例子:
效果预览:
安装
iframe方式直接将html代码导入到自己的网站中即可:
1
| <iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=450 src="//music.163.com/outchain/player?type=0&id=6890823962&auto=1&height=430"></iframe>
|
插件使用:Aplayer+MetingJS
- 安装插件
- 官方直接安装:
官方文档
- 插件hexo-tag-aplayer安装:
官方文档
- 从CDN库引用到对应的网页文件中(可独立可插入head/body):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css"> <script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/meting@2.0.1/dist/Meting.min.js"></script> </head> <body> <meting-js server="netease" type="playlist" id="60198"></meting-js> </body> </html>
|
- 使用参数中文版
Pjax的使用:网页刷新不中断播放器播放
原理
pjax是jquery的一个插件,它使用ajax和pushState两个技术改善用户的网页浏览体验。具体来说,当用户使用a标签切换页面时,可以实现局部刷新的技术。(next主题配置中有自带,把pjax配置修改为true即可
)
Pjax 又是啥?别急,听在下说说新的麻烦:
沉浸中欢乐的歌声中,随便点了一个页内跳转,网页开始刷新,但是!但是!但是!音乐播放器也跟着刷新了,从头开始播放?!Excuse Me?这也太傻了吧…
转念细想,其实按上面的教程,是在每个 html 页面上都加上了 APlayer 的加载代码,页面刷新的时候,上个页面自然的就被替换成了新的页面,APlayer 就相当于重新加载了一次。所以,讲道理,这段代码应该只用加载一次,并且不能随着网页跳转而改变,就像被我埋没多年的 QQ 空间那样(每次翻看太多黑历史了,但音乐播放器是优秀的)。
网上有人说可以用框架做,就是一个框架中嵌入 APlayer,另一个用于页面跳转;也有人说用 Pjax,它可以做到无刷新 ajax 加载。考虑再三(也就几秒钟),肯定抛弃前者这种过时的方法,积极拥抱 jQuery-Pjax 。原文链接:https://blog.csdn.net/PingXiaoGai/article/details/113448237
从我这个js新手的角度来看,每一次点击网页或者博客内的链接,网页都会重新加载一次,这不免会导致有些操作是重复多余的,如果可以使用某个容器把要更新的body框起来,其他的部分不受影响,这样就可以既浏览博客内的网页,又不会影响播放器全局的播放(nice)。
注明:我使用的主题是Noemoe,全改动都在layout.ejs中配置
一不做二不休,开干!
head引入Pjax
- 老样子,从CDN下发中引入插件(head部分插入如下代码)
1 2 3
| <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>
|
- 然后在body中将要替换(局部更新)的内容用 div 圈起来,id自定义,另外播放器也圈起来类似如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <body> ... <div id="pageContent"> </div> <div id="aplayerContent"> </div> <script> $(document).pjax('a[target!=_blank]', '#pageContent', {fragment: '#pageContent', timeout:8000}) </script> ... </body>
|
就此大功告成!开始我们的素质三连体验吧~
1 2 3
| hexo clean hexo g hexo s
|
迷你版参数代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css"> <script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/meting@2.0.1/dist/Meting.min.js"></script> </head> <body>
<meting-js server="netease" type="playlist" id="60198" fixed="true" autoplay="true" loop="all" order="random" preload="auto" list-folded="ture" list-max-height="500px" lrc-type="1"> </meting-js>
</body> </html>
|
如果你是分别独立放入css,js中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">
<script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/meting@2.0.1/dist/Meting.min.js"></script> <meting-js server="netease" type="playlist" id="60198" fixed="true" autoplay="true" loop="all" order="random" preload="auto" list-folded="ture" list-max-height="500px" lrc-type="1"> </meting-js>
|
最后附上我的layout.ejs代码(swg等网页配置类型文件同理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| <!DOCTYPE html>
<html <% if (config.language) { %>lang="<%- config.language %>"<% } %>>
<head> <% var title = page.title;
if (is_archive()){ title = __('archive');
if (is_month()){ title += ':' + page.year + '/' + page.month; } else if (is_year()){ title += ':' + page.year; } } else if (is_category()){ title = __('count.categories') + ':' + page.category; } else if (is_tag()){ title = __('count.tags') + ':' + page.tag; } %> <title><% if (title){ %><%= title %> - <% } %><%= config.title %></title> <meta charset="UTF-8"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css"> <script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/meting@2.0.1/dist/Meting.min.js"></script> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/jquery.pjax/2.0.1/jquery.pjax.min.js"></script> <meta name="description" content="<%= config.description %>"> <meta name="keywords" content="<%= config.keywords %>"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5"> <%- partial('_partial/_analytics/gtm-head') %> <%- partial('_partial/site-verification') %> <link rel="shortcut icon" href="<%= theme.favicon.href %>" type="<%= theme.favicon.type %>" /> <%- open_graph({twitter_id: theme.twitter, google_plus: theme.google_plus, fb_admins: theme.fb_admins, fb_app_id: theme.fb_app_id}) %> <link rel="stylesheet" href="https://cdn.jsdelivr.net/combine/npm/highlight.js@9.15.8/styles/atom-one-dark.css,npm/justifiedGallery@3.8.1/dist/css/justifiedGallery.min.css,gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css,npm/hexo-theme-nexmoe@latest/source/lib/mdui_043tiny/css/mdui.css,npm/hexo-theme-nexmoe@latest/source/lib/iconfont/iconfont.css?v=233" crossorigin> <%- css_auto_version('css/style') %> <% if (theme.function.darkmode) { %> <%- css_auto_version('css/dark') %> <% } %> <% if (theme.iconlib) { %> <link rel="stylesheet" href="<%= theme.iconlib %>"> <% } %> <%- css_auto_version('lib/iconfont/iconfont.css') %> <% if (theme.customstyle) { %> <link rel="stylesheet" href="/custom.css"> <% } %> </head>
<body class="mdui-drawer-body-left"> <%- partial('_partial/_analytics/gtm-body') %> <div id="pageContent"> <div id="nexmoe-background"> <div class="nexmoe-bg" style="background-image: url(<%= theme.background.path %>)"></div> <div class="mdui-appbar mdui-shadow-0"> <div class="mdui-toolbar"> <a mdui-drawer="{target: '#drawer', swipe: true}" title="menu" class="mdui-btn mdui-btn-icon mdui-ripple"><i class="mdui-icon nexmoefont icon-menu"></i></a> <div class="mdui-toolbar-spacer"></div> <a href="<%- url_for() %>" title="<%= config.author || config.title %>" class="mdui-btn mdui-btn-icon"><img src="<%= theme.avatar %>" alt="<%= config.author || config.title %>"></a> </div> </div> </div> <div id="nexmoe-header"> <%- partial('_partial/header') %> </div> <div id="nexmoe-content"> <div class="nexmoe-primary"> <%- body %> <div class="nexmoe-post-right"> <div class="nexmoe-fixed"> <div class="nexmoe-tool"> <% if (page.toc || theme.function.globalToc){ %> <% const toc_obj = toc(page.content, {list_number: true}); %> <% if (toc_obj.length > 0) { %> <button class="mdui-fab catalog" style="overflow:unset;"> <i class="nexmoefont icon-i-catalog"></i> <div class="nexmoe-toc"> <%- toc_obj %> </div> </button> <% } %> <%} %> <a href="#nexmoe-content" class="toc-link" aria-label="回到顶部" title="top"><button class="mdui-fab mdui-ripple"><i class="nexmoefont icon-caret-top"></i></button></a> </div> </div> </div> </div> </div> </div> <div id="aplayerContent"> <meting-js style="position:absolute; z-index:99999" type="playlist" server="netease" id="6976153408" fixed="true" autoplay="true" order="random" loop="all" list-folded="false" preload="auto" list-max-height="500px" lrc-type="1"> </meting-js> </div> <script> $(document).pjax('a[target!=_blank]', '#pageContent', {fragment: '#pageContent', timeout:8000}) </script> <%- partial('_partial/searchbox') %> <%- partial('_partial/after-footer') %> <%- partial('_partial/analytics') %> </body>
<canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas> <script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script> <script type="text/javascript" src="/js/firework.js"></script>
<script type="text/javascript" src="/js/click_show_text.js"></script> </html>
|