|
29 | 29 | <script src=" //cdn.jsdelivr.net/gh/love2wind/[email protected]/spzac/js/instant.page.js" type=" module" ></script>
|
30 | 30 | <link rel="dns-prefetch" href="//cdn.jsdelivr.net/" />
|
31 | 31 | <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> |
32 | 208 | <style type="text/css">
|
33 | 209 | body {
|
34 | 210 | /*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