经验向:使用HEXO的两个小坑以及一个效率优化

前言

先说两个坑,都是关于视频播放的,一个是博客页面的video无法全屏播放,另一个是hexo generate时如果文件过大的话会改变文件的内容,通常出现在加载第三方js或css库,这里我是加载一个H5视频的库。

而效率优化则是如何简化命令书写的


坑之一:H5视频无法全屏播放

问题如下:点击全屏播放的按钮后视频不见了只有背景的轮播图片了,如图1

图1

这个问题是由于这个轮播图片的插件对其中的ul的css样式设定了position: fixed;,如图2

图2

这会貌似会使其悬浮于全屏视屏标签的上方,因为Chrome为全屏视频标签添加的css也只是如下图3所示的样子,虽然我对css不太熟悉,但觉得relative还是干不过fixed

图3

那么,如果一开始把轮播图片的问题去掉的话,也就是把position:fixed;去掉会怎么样呢,结果发现视频被框在一个小范围之中,如图4

图4

应该是包裹文章的div的css样式的问题,wtf,我不想再去研究css了…

那问题来了,怎么办?

我后来想到的思路是:在视频全屏之前把第一个小问题的position:fixed;去掉,同时把整体页面隐藏,并让包含video的标签成为body的子节点,如下图5所示

图5

点击退出全屏时在将之前的操作复原,完美解决问题。

由于我使用的Plyr提供了相关的api接口,所以我可以方便地编写代码如下

相关的Plyr的API见其文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// 初始化第三方播放器
PowerfulVideo.prototype.initPlyr = function(playerId) {
// 初始化
this.player = new Plyr(playerId);
// 在播放器div容器之前添加一个标注tag,以便退出全屏的时候找到原来的位置
var $anchor = document.createElement('div');
$anchor.setAttribute('id', 'video_anchor');
this.$videowrapper.parentNode.insertBefore($anchor, this.$videowrapper);

// 找到全屏按钮并为其添加监听事件
var a = document.getElementsByClassName('plyr__control');
var fullbtn;
for (var i = 0; i < a.length; i++){
if (a[i].getAttribute('data-plyr') === 'fullscreen'){
fullbtn = a[i]
}
fullbtn.onclick = function() {
// 背景轮播图
var $bgan = document.getElementsByClassName('cb-slideshow')[0];
// 包含视频标签的div
var $vw = document.getElementById('video_wrapper');
// 页面主体div
var $mainc = document.getElementById('container');

// 如果当前为全屏状态,则点击按钮后恢复全屏,否则全屏
if (this.player.fullscreen.active) {
this.player.fullscreen.exit()
// 恢复背景图片显示
$bgan.style.position = "fixed";
// 显示页面主体
$mainc.setAttribute("style", "");
// 插入到原来的位置
document.body.removeChild($vw);
$anchor.parentNode.insertBefore($vw, $anchor.nextSibling);
} else {
// 修复全屏时背景图片问题
$bgan.style.position = "";
// 隐藏文章主体
$mainc.style.display = "none";
// 将视频标签加到body的下面
document.body.appendChild($vw);
// 进入全屏
this.player.fullscreen.enter();
}
}.bind(this);

// 处理全屏按esc退出的事件
this.player.on('exitfullscreen', function(event) {
var $bgan = document.getElementsByClassName('cb-slideshow')[0];
var $vw = document.getElementById('video_wrapper');
var $mainc = document.getElementById('container');
console.log('capture');
$bgan.style.position = "fixed";
$mainc.setAttribute("style", "");
if ($anchor.nextSibling !== $vw) {
document.body.removeChild($vw);
$anchor.parentNode.insertBefore($vw, $anchor.nextSibling);
}
}.bind(this));
}

坑之二:hexo generate加载大文件时出错

是的,这个错误莫名奇妙,如图6,它居然给我把文件改了

图6

这是我之前使用video.js时加载它的js文件,貌似是因为文件比较大吧

对于hexo generate,它的作用应该是把各种资源文件合并放到public文件夹中,包括Markdown转成html,各种HTML文件的合成,css,js,image资源的合并,但是,我认为第三方库并不需要处理,所以可以把这些文件集中放到一个独立的文件夹中,再执行完hexo generate后再把它拷进去,如图7

图7

那每次都要手动拷贝太麻烦了不是吗,下面就来讲一个效率优化


效率优化

多希望每次就敲一个命令就好了,对不对,所以写一些脚本吧

~/.bash_profile

1
2
3
4
5
6
7
8
9
10
11
# 设定hexo目录
export MY_BLOG_HOME=~/workspace/my-blog
# 设定一些别名
# 启动本地预览服务器
alias hexo_local="cd $MY_BLOG_HOME && npm run local"
# 部署到远程服务器
alias hexo_deploy="cd $MY_BLOG_HOME && npm run deploy"
# 到hexo根目录
alias hexo_blog_home="cd $MY_BLOG_HOME"
# 到hexo博客资源目录
alias hexo_blog_post_src="cd $MY_BLOG_HOME/source/_posts"

package.json

1
2
3
4
5
6
...
"scripts": {
"local": "hexo clean && hexo g && cp -r $MY_BLOG_HOME/third-party $MY_BLOG_HOME/public &&hexo s",
"deploy": "hexo clean && hexo g && cp -r $MY_BLOG_HOME/third-party $MY_BLOG_HOME/public && hexo d"
}
...

这样子我每次要到达博客根目录,本地预览,远程部署分别就敲hexo_blog_home,hexo_local,hexo_deploy就可以了,方便快捷