发现问题的过程
刚刚在浏览博文的时候发现代码高亮没有加载成功,而刷新页面就可以加载
刚开始以为是缓存的问题,然而后来发现只要是从首页进入,就必须刷新一次才能加载高亮
解决问题的过程
由于此主题作者大量使用了ajax/pjax异步狂魔,我迅速意识到这是由于博客异步加载文章出现的bug
由于MathJax是支持异步的,所以我下意识认为Prismjs也支持,并没有意识到问题所在
我先是猜想我用的PrismJs的管理插件出了问题,手动在footer.php中加上了PrismJs的外链,问题并没有得到解决
这时我才意识到PrismJs出了问题,于是百度一波PrismJs ajax,果然,问题就是PrismJs不支持异步
但我并不知道PrismJs中有没有手动高亮的方法,于是又百度一波,找到了以下两个方法:
方法一
Prism.highlightAll();
这个方法可以重新加载页面上所有的代码高亮, 缺点是资源占用较高, 好在简单粗暴
只要在页面pjax加载完毕后重新加载一遍代码高亮即可, 于是我在主题的主要js文件中写上:
document.addEventListener('pjax:complete', Prism.highlightAll());
但是得到的反馈却是Prism.highlightAll() is not a function, emmm这部分至今不知道怎么回事
Update: 是我自己疏忽,这个方法是完全可以的
于是我试了方法二
方法二
Prism.highlightElement(block);
这个方法会渲染某个指定block里的代码
但我并没有找到说block是什么对象, 于是我先用document.getElementsByTagName
来试试,套上forEach,结果渲染了几个代码块就报错了,报错信息是:
Uncaught TypeError: Cannot read property 'children' of undefined
通过console.log,我发现报错的那个代码块算是渲染完毕了,于是我在Prism.highlightElement(block);
两侧套上trycatch,虽然控制台还是报错不断,但是问题算是解决了
但是控制台一片红我还是看着不爽, 于是看了一下同一个文件中作者使用highlight.js的写法,他使用的是document.querySelectAll
,虽然我认为可能并不互通,但还是试了一下,问题完美解决,没有任何报错
再在两边加上trycatch以防万一,最终我的解决方案是这样的:
document.addEventListener('pjax:complete', function(){
var codes = document.querySelectorAll('code');
[].forEach.call(codes,function(block){
try{
Prism.highlightElement(block);
}catch(e){}
});
});
其它方法
可以模仿百度统计脚本的加载, 在pjax完成后才开始获取PrismJs的外链(用这种方法的同学注意改一下链接qwq):
(function() {
src = ["http://ela.moe/usr/plugins/Prismjs/prism.js","http://ela.moe/usr/plugins/Prismjs/line-number-wrap-fix.js"];
[].forEach.call(src, function(e){
var hm = document.createElement("script");
hm.src = e;
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})
})();
但既然PrismJs已经自带解决方案了,我觉得这种方法没有必要
总结
- 渲染页面的工作最好等到异步加载完成后再进行MathJax:你说啥?
- 我真的要去补补js了QAQ
评论