Next主题小屏幕下保留侧边栏

这篇文章的启发,决定改下主题使得手机(平板)浏览器也能弹出侧边栏。当然,iissnan最初决定在小屏幕上block掉侧栏是有原因的,这个副作用在这番改动之后也依然存在:极端尺寸设备上会出现侧栏完全覆盖主体甚至显示不全。改动的好处也很明显,页面内容展示更完全。毕竟H5普及之后,小型网站越来越不需要考虑兼容性问题,权衡利弊,这样做还是有意义的。

恢复侧栏开关

这一步参考上面提到的那篇教程。

启用侧边栏

打开source/css/_common/components/sidebar/sidebar.styl,删掉或注释掉

1
2
3
4
5
6
+tablet() {
display: none !important;
}
+mobile() {
display: none !important;
}
启用按钮

首先是侧边栏开关,打开source/css/_common/components/sidebar/sidebar-toggle.styl,在.sidebar-toggle下修改

1
2
3
4
5
6
7
8
+tablet() {
right: 20px;
opacity: 0.8;
}
+mobile() {
right: 20px;
opacity: 0.8;
}

这里在解除隐藏的同时微调了显示效果。
然后是back-to-top按钮,类似的,打开source/css/_common/components/back-to-top.styl,在.back-to-top下修改

1
2
3
4
5
6
7
8
+tablet() {
right: 20px;
opacity: 0.8;
}
+mobile() {
right: 20px;
opacity: 0.8;
}

到这里已经实现了目标,但触摸屏上关闭侧边栏最方便的还是点击外围区域或者滑动,这里选择前一种实现方式。

增加关闭侧栏的方式

策略很简单,增加一个覆盖层与侧栏联动,点击覆盖层触发侧栏开关按钮的点击事件。首先修改layout/_macro/sidebar.swig,增加sidebar-dimmer层

1
2
3
<aside id="sidebar" class="sidebar">
<div id="sidebar-dimmer"></div>
<div class="sidebar-inner">

定义sidebar-dimmer的样式,这里我把代码放在source/css/_common/components/sidebar/sidebar-toggle.styl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.sidebar-active #sidebar-dimmer {
opacity: .7;
-webkit-transform: translateX(-150%);
transform: translateX(-150%);
transition: opacity .2s;
}

#sidebar-dimmer {
display: none;
position: absolute;
top: 0;
left: 100%;
width: 200%;
height: 100%;
background: #000;
opacity: 0;
transition: opacity .2s,transform 0s .2s;
+mobile() {
display: block;
}
}

dimmer宽度倍率x和左移倍率y需要满足y=1+1/x的关系才能在侧栏展开时与dimmer右边界形成良好的衔接,所以需要根据mobile view最大宽度调整x的值。这里图省事把x设定为200%,y自然是150%了。
最后添加触发条件,修改source/js/src/motion.js

1
2
3
4
5
6
7
8
9
10
var sidebarToggleMotion = {
toggleEl: $('.sidebar-toggle'),
dimmerEl: $('#sidebar-dimmer'), //init
sidebarEl: $('.sidebar'),
isSidebarVisible: false,
init: function () {
this.toggleEl.on('click', this.clickHandler.bind(this));
this.dimmerEl.on('click', this.clickHandler.bind(this)); //binding
this.toggleEl.on('mouseenter', this.mouseEnterHandler.bind(this));
this.toggleEl.on('mouseleave', this.mouseLeaveHandler.bind(this));

到这里基本完成,存在的问题是覆盖层只占据侧栏左边的区域,如果侧栏在左边,还需要较大的改动,但是基本原理不会变。