前情提要
Material Theme这套博客主题大约用了半年了,我很喜欢这套主题,很多元素基于Material Design初代设计(讲真,我真的不喜欢Material Design 2的卡片化,去线留白和底栏设计,从UI到操作充满了割裂感)但这套主题的确是缺少很多实用的功能,比如夜间模式,不支持图片灯箱,一开始也没有Pjax支持等等......为此我也进行了不少魔改,让这个博客主题既耐看又实用。
因此趁着寒假时间比较充裕,这次我就想给博客加一个图片灯箱功能。我之前使用的Raw主题就支持图片灯箱,使用的就是这个FancyBox,很多其他主流的主题使用的也都是这个图片灯箱。因此我决定给Material Theme加上FancyBox灯箱。
添加FancyBox灯箱
fancyBox是一款优秀的弹出框Jquery插件。能快速预览大图,快速放大图片,支持使用鼠标滚轮和键盘切换图片,能够将页面中的所有照片合成相册,幻灯片自动播放等等......总之,FancyBox是灯箱插件中相当好用的一个。
先把官网贴上:https://fancyapps.com/fancybox/3/
Github地址:https://github.com/fancyapps/fancybox
先使用CDN引入CSS和JS,FancyBox需要Jquery支持:
<link href="https://cdn.jsdelivr.net/npm/@fancyapps/[email protected]/dist/jquery.fancybox.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/[email protected]/dist/jquery.fancybox.min.js" type="ee71b4ea12285dc3ed787f94-text/javascript"></script>
这里我们只使用FancyBox的基本功能,不需要进行初始化,FancyBox的基本功能就很强大了。
对typecho模板PHP代码的修改:
修改模板的post.php: 将模板中的
<?php $this->content(); ?>
修改成:
<?php
$pattern = '/\<img.*?src\=\"(.*?)\"[^>]*>/i';
$replacement = '<a href="$1" data-fancybox="gallery" /><img src="$1" alt="'.$this->title.'" title="点击放大图片"></a>';
$content = preg_replace($pattern, $replacement, $this->content);
echo $content;
?>
即可。这段代码的作用是将原来输出文章内容中的img标签
进行替换,使之能够被FancyBox选择。如果还有其他独立页面,也可以进行修改。如果你的博客没有Pjax支持,现在就大功告成了,很简单不是?
修复FancyBox的Pjax支持
我魔改的Material Theme使用的Pjax并不是Github上star数最多的Jquery-pjax,而是另一款不需要Jquery支持的Pjax插件。
尽管我的博客引入了Jquery,但这款插件能够用在无Jquery的其他页面上,因此我最终还是学习了不需要Jquery的Pjax插件:MoOx/pjax。然而Pjax支持是我修改这个主题的一个大坑...
FancyBox灯箱能够正常被激活并使用。但是,当关闭FancyBox灯箱时,页面会重载一次。
这个问题困扰了我一段时间,百思不得其解......
最终,我在Hexo的issue中找到了一个跟我有相同遭遇的人,链接在此:
With PJAX, the page will refresh once after closing the image's fancybox window
Hexo项目中使用的Pjax正是我使用的MoOx/pjax,阅读上述issue,查看Hexo作者的在Github的commit后,我知道了症结所在:需要关闭FancyBox的hash模式,以止地址栏变化。因为Pjax插件检测到地址栏变化后,误以为加载了不同的页面,于是对整个页面进行重载。Hexo的commit地址在此。
最终的解决方案:在页脚加入JS代码如下:
<script type="text/javascript">
$(document).ready(function () {
$.fancybox.defaults.hash = false;
});
</script>
至此,FancyBox已经可以在我魔改的Material Theme上正常运行了。