Skip to content

Commit c5c5e75

Browse files
committed
add Aplayer
1 parent 2043b98 commit c5c5e75

File tree

2 files changed

+453
-0
lines changed

2 files changed

+453
-0
lines changed

docs/index.html

+176
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,182 @@
2929
<script src="//cdn.jsdelivr.net/gh/love2wind/[email protected]/spzac/js/instant.page.js" type="module"></script>
3030
<link rel="dns-prefetch" href="//cdn.jsdelivr.net/" />
3131
<link rel="dns-prefetch" href="//fonts.googleapis.com" />
32+
<script>
33+
// APlayer API
34+
document.addEventListener('DOMContentLoaded', initAplayer);
35+
window.aplayers = window.aplayers || [];
36+
function initAplayer(option) {
37+
const common = {
38+
loadResource: function (id, resource, type) {
39+
return new Promise(function (resolve, reject) {
40+
let loaded = document.head.querySelector('#' + id);
41+
if (loaded) {
42+
resolve('success: ' + resource);
43+
return;
44+
}
45+
const element = document.createElement(type);
46+
element.onload = element.onreadystatechange = () => {
47+
if (!loaded && (!element.readyState || /loaded|complete/.test(element.readyState))) {
48+
element.onload = element.onreadystatechange = null;
49+
loaded = true;
50+
resolve('success: ' + resource);
51+
}
52+
}
53+
element.onerror = function () {
54+
reject(Error(resource + ' load error!'));
55+
};
56+
if (type === 'link') {
57+
element.rel = 'stylesheet';
58+
element.href = resource;
59+
} else {
60+
element.src = resource;
61+
}
62+
element.id = id;
63+
document.getElementsByTagName('head')[0].appendChild(element);
64+
});
65+
},
66+
loadResources: function (callback) {
67+
const loadResource = this.loadResource;
68+
const pt = '//s0.pstatp.com/cdn/expire-1-M/';
69+
const jd = '//cdn.jsdelivr.net/npm/';
70+
const resources = [
71+
pt + 'aplayer/1.10.1/APlayer.min.css',
72+
pt + 'aplayer/1.10.1/APlayer.min.js',
73+
jd + 'meting@2/dist/Meting.min.js'
74+
];
75+
const loadPromises = [];
76+
resources.forEach(resource => {
77+
loadPromises.push(loadResource(btoa(resource).replace(/[=+\/]/g, ''), resource,
78+
({
79+
'css': 'link',
80+
'js': 'script'
81+
})[resource.split('.').pop()]
82+
));
83+
});
84+
Promise.all(loadPromises).then(
85+
function () {
86+
if (typeof callback !== 'function') return;
87+
let flag = false;
88+
const waitAM = setInterval(() => {
89+
if (!flag
90+
&& typeof APlayer === 'function'
91+
&& typeof MetingJSElement === 'function') {
92+
flag = true;
93+
callback();
94+
clearInterval(waitAM);
95+
}
96+
}, 100);
97+
}
98+
);
99+
},
100+
createAplayers: function (sources) {
101+
for (let i = 0; i < sources.length; i++) {
102+
const child = document.createElement('div');
103+
sources[i].parentNode.insertBefore(child, sources[i]);
104+
sources[i].style.display = 'none';
105+
const songsTag = sources[i].querySelectorAll('s');
106+
const songs = [];
107+
songsTag.forEach(songTag => {
108+
const song = {};
109+
for (let i = 0; i < songTag.attributes.length; i++) {
110+
song[songTag.attributes[i].name] = songTag.attributes[i].value;
111+
}
112+
songs.push(song);
113+
});
114+
const options = { container: child, preload: 'none', autoplay: false, audio: songs };
115+
const optionMap = sources[i].attributes;
116+
for (let i = 0; i < optionMap.length; i++) {
117+
options[optionMap[i].name] = optionMap[i].value;
118+
}
119+
this.loadResources(() => window.aplayers.push(new APlayer(options)));
120+
}
121+
}
122+
};
123+
124+
if (option == 'manual') return new Promise((resolve, reject) => {
125+
common.loadResources(() => resolve('success'));
126+
});
127+
128+
const aps = document.querySelectorAll('ap');
129+
if (aps.length !== 0) common.createAplayers(aps);
130+
131+
const mts = document.querySelectorAll('meting-js');
132+
if (!window.refreshing && mts.length !== 0) common.loadResources(
133+
function () {
134+
mts.forEach(mt => {
135+
if (!mt.aplayer) {
136+
const html = mt.outerHTML;
137+
mt.aplayer = { destroy: new Function(), list: { index: undefined } };
138+
mt.outerHTML = '\n' + html;
139+
}
140+
});
141+
document.querySelectorAll('meting-js').forEach(mt => {
142+
let flag = false;
143+
const waitMT = setInterval(() => {
144+
if (!flag && mt.aplayer) {
145+
flag = true;
146+
window.aplayers.push(mt.aplayer);
147+
console.log('replaced unloaded aplayer.')
148+
clearInterval(waitMT);
149+
}
150+
}, 300);
151+
});
152+
}
153+
);
154+
}
155+
</script>
156+
157+
<script>
158+
// PJAX 相关 BUG
159+
document.addEventListener('DOMContentLoaded', function () {
160+
let flag = false;
161+
window.needReloadUrls = window.needReloadUrls || new Set();
162+
const jqueryWaitor = setInterval(() => {
163+
if (!flag && jQuery) {
164+
flag = true;
165+
$(document).on('pjax:start', function () {
166+
if (!window.refreshing || !window.pjaxStarted) {
167+
window.pjaxStarted = true;
168+
console.log('pjax:start');
169+
window.aplayers.forEach(ap => {
170+
ap.list.index = undefined;
171+
ap.destroy();
172+
});
173+
window.aplayers = [];
174+
setTimeout(() => window.pjaxStarted = false, 2000);
175+
}
176+
});
177+
$(document).on('pjax:end', function () {
178+
if (document.querySelector('meting-js')
179+
|| document.querySelector('.collapse-block')
180+
|| document.querySelector('#toggle-menu-tree')
181+
|| document.querySelectorAll('.content-tab-title').length > 1
182+
) {
183+
if (!window.needReloadUrls.has(location.href)) {
184+
window.needReloadUrls.add(location.href);
185+
console.log('captured a neededReloadUrl.');
186+
}
187+
}
188+
});
189+
$(document).on('pjax:popstate', function (event) {
190+
if (event.state && window.needReloadUrls.has(event.state.url) && !window.refreshing) {
191+
window.refreshing = true;
192+
console.log('back-forward handler.');
193+
$.pjax.reload({
194+
url: location.href,
195+
container: '#body',
196+
fragment: '#body',
197+
scrollTo: false,
198+
timeout: 8000
199+
});
200+
setTimeout(() => window.refreshing = false, 2000);
201+
}
202+
});
203+
clearInterval(jqueryWaitor);
204+
}
205+
}, 500);
206+
});
207+
</script>
32208
<style type="text/css">
33209
body {
34210
/*font-family: "Noto Sans CJK SC", "PingFang SC", "Microsoft Yahei UI", "Microsoft Yahei", -apple-system, BlinkMacSystemFont, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Noto Color Emoji;*/

0 commit comments

Comments
 (0)