Discuz! 论坛评分刷新机制会连带帖子内容一同刷新,通过ES6模块实现特效功能的音画帖基本上无法适配该刷新机制,原因主要是script标签的module属性得不到继承与延续——Discuz刷新模板重置帖子时不支持script标签的 type="module" 的属性设置。为此,如果需要相对完美适配其刷新机制,只能放弃简洁而方便的ES模块,回退到传统加载JS资源的方案。但 Discuz! 又不接受script标签的行内资源加载方式,我们唯一的选择是代码量较大的动态加载方法,下面是类似于过去曾经介绍过的加载JS文件函数:
function loadJs(url, callback) {
const script = document.createElement('script');
script.charset = 'utf-8';
script.src = url;
script.defer = true;
script.onload = callback;
document.head.appendChild(script);
}
函数需要两个参数:参数1是JS文件地址,参数2是一个回调函数,即渲染帖子完整效果的封装函数。函数体中,一,设置编码为 utf-8 以防止非 utf-8 编码的页面出现中文乱码,设置 defer 属性为 true 意在异步执行资源的加载和核心函数的运行次序;二,在资源加载成功后(onload)运行回调函数即待传入的渲染帖子的函数;三,最后将JS资源标签追加到head标签中。为了简洁,函数没有做出错处理,但需要一切正常,特别地,JS文件地址必须有效。
接着将做帖的JS代码封装为一个函数,这里以 tzMaker 非ES版 v5 为例,代码样式如下:
function tzInit() {
var tz = TZ('pa');
tz.add('audio', '', '', { src: '音频地址' });
tz.add('video', '', 'vid', { src: '视频地址' });
tz.add('img', '', 'ma', { src: '播放器图片地址'}).playmp3();
tz.bgprog().style('bottom: 20px; color: aliceblue');
tz.fs().style('right: 20px; top: 20px');
tz.autoMid();
}
就是说,tz 指令语句全放在一个渲染帖子的初始化函数内,该函数将被 loadJs() 函数作为第二个参数进行回调,这样就可以保证运行秩序的顺延,即JS文件先加载、完了再渲染帖子的具体内容,核心就是 tz 指令所依赖的JS资源已经准备就绪、可以开工。
下来是上述函数的应用示例:
var jsfile = './tz.v5.js';
loadJs(jsfile, tzInit);
注意全局变量要使用 var 关键字声明,不然的话 Discuz! 论坛在评分后的刷新过程中也会抛弃其继承性。
为方便大家使用,下面给出一个完整的基于 tzMaker v5 非ES模块版的代码模板:
<style>
@import 'https://638183.freep.cn/638183/tzmaker/tz.v5.css';
.pa { --bg: tan url('帖子背景图片地址') no-repeat center/cover; }
</style>
<div class="pa"></div>
<script>
var jsfile = 'https://638183.freep.cn/638183/tzmaker/tz.v5.min.js';
loadJs(jsfile, tzInit);
function loadJs(url, callback) {
const script = document.createElement('script');
script.charset = 'utf-8';
script.src = url;
script.defer = true;
script.onload = callback;
document.head.appendChild(script);
}
function tzInit() {
var tz = TZ('pa');
tz.add('audio', '', '', { src: '音频地址' });
tz.add('video', '', 'pd-vid', { src: 视频地址' });
tz.add('img', '', 'ma invert', { src: '播放器图片地址', style: 'bottom: 65px' }).playmp3();
tz.bgprog().style('bottom: 20px; color: aliceblue');
tz.fs().style('right: 20px; top: 20px');
tz.autoMid();
}
</script>
如果做LRC歌词帖,建议歌词的变量声明也用 var 声明,放在 jsfile 变量声明的上面。另外,如果你有自己的空间,CSS和JS资源文档可以上传到自己的空间,使用时改一下CSS和JS的地址。
【附】动态加载JS文件的函数可以考虑使用 Promise 对象实现,这样可以加入出错处理,增强函数的健壮性能。