emmmmmmm标题实在想不到怎么起。其实效果大概是这样的:
而标题,也许是我当时看到这种效果时的真实感受。因为第一反应是:“还可以把page整体移出页面?”
发现:display动画的应用
整件事的起因是什么呢?在笔者最近为社团计划的官网上打算做一个这样的效果:点击头像,左边/右边滑出一个“面板”,里面展示用户的个人信息。
当然,这有很多种做法,比如:利用position定位+overflow溢出隐藏、利用opacity/visibility隐藏+pointer-events元素穿透… 但是笔者当时想到的是如何给”真正的隐藏,display “加上动画!
我们大概都知道的是:HTML渲染过程中有一个可能执行的、影响页面性能的“回流”和“重绘”的过程。导致这个过程被触发的原因有很多:元素位置移动、大小改变、增删节点以及这里要说的display显示与隐藏切换等等。而元素的变动需要页面快速的显示出来,所以在我们看来是“突兀”的。 而且有一点需要注意的是:浏览器是“有点智能”的 —— 它可以判断如果会触发页面回流的代码有很多,那么它会将这些代码都读取完再(合并)一起执行 ,所以这也是下面这段代码会有如下图效果的原因:
width : 50px;
height : 50px;
background-color : red;
display : none;
transform : translateX ( 0) ;
transition : all .6s ease; //似乎没用?
ds. style. display= "block" ;
ds. style. transform= "translateX(100px)" ;
但是同样的,当对以下属性进行操作的时候,由于浏览器的渲染机制有一些API可以使页面强制渲染(因为要获得详细确切的信息),包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。这会直接导致前后两行相当于“渲染了两遍”。
所以将上方js代码改为下面这样:
ds. style. display= "block" ;
ds. offsetHeight;
ds. style. transform= "translateX(100px)" ;
就可以了
目前csdn官网PC端blink发布页面的图片上传就用了类似这个功能!
后来还是觉得这种方式需要涉及js对页面结构的改变,于是乎…
实现:如何实现文首展示的效果
这基于position定位是会“重合”的:在两个行内元素都设置了定位属性(但没有加top/left/bottom/right定位)后,后面的会覆盖前面的;这时候可以通过margin移动位置展示 。
只能是行内元素,行内块元素都不行。 ——云小梦
它大概结构是这样的:
< div class = " page_list" >
< div class = " z_two_page" >
</ div>
< div class = " box" >
< div class = " zb_mask" > </ div>
</ div>
< div class = " space" > </ div>
</ div>
实际就像这样的:
< div class = " page_list" >
< div class = " z_two_page" > 哈哈哈</ div>
< div class = " box" >
< div class = " zb_mask" > </ div>
< div id = " boxs" >
< div class = " left" style =" background-color : #ffc5c5; " > </ div>
< div class = " right" style =" background-color : #7171f7; " >
flex下两列布局左边固定右边宽高自适应
</ div>
</ div>
< div class = " color" > </ div>
< a href = " #" class = " a" > 千万小心像对a设置全局样式(这叫啥样式重置)</ a>
< div class = " center" >
< div class = " ds" > </ div>
< button class = " but" > 到指定地点</ button>
</ div>
< form id = " form" action = " #" >
<input type="submit" value="="踢脚板 />
</ form>
< img id = " img" src = " compress/compress/img/mxc_16x16.png" />
</ div>
< div class = " space" > </ div>
</ div>
如上,class为“box”的div里面放的就是“原本的页面整体”部分。为了达到想要的效果,我们采用了flex布局!
flex简写时包括三个属性:flex-grow、flex-shrink和flex-basis ——
flex-grow:指定了容器剩余空间多余时候的分配规则,默认值是0,多余空间不分配;
flex-shrink:指定了容器剩余空间不足时候的分配规则,默认值是1,空间不足要分配;
flex-basis:flex-basis则是指定了固定的分配数量,默认值是auto。设置的同时需设置width或者height属性;
.page_list {
width : 100vw; display : flex; overflow-y : hidden; }
.box {
flex : 0 0 100vw; height : 100%; background-color : #fff; position : relative; overflow-y : auto; overflow-x : hidden; transition : all .6s ease; }
.zb_mask {
position : absolute;
top : 0;
left : 0;
width : 100%;
height : 100%;
z-index : 100;
background-color : rgba ( 0,0,0,.2) ;
pointer-events : none;
opacity : 0;
transition : all .6s ease;
}
.space {
flex : 0 0 12rem; }
.z_two_page {
width : 12rem; position : fixed; right : 0; top : 0; }
大概就是:什么也不干的情况下只展示box的内容(也就是和不加这些花里胡哨的div一样的效果),它是用background覆盖后面的class为“space”的占位元素;在”哈哈哈“展示的时候,box右移。
这里需要注意的是:为什么“哈哈哈”所属div在前而“页面”所属div在后? 因为根据前面所说,这里采用的是position覆盖,它的规则就是“后面的覆盖前面的”,所以如果采用这种布局方式,那么一开始被隐藏的元素就要放在前面。
代码中flex的前两个属性值为0,表示在空间增大或缩小时依然保持原状(这是本文的基础!),第三个元素则写了展示时的“默认大小”:如你所看,box承载的是页面,所以它是100vw,而class为“z_two_page”的元素这里设置了12rem ,你完全可以将这个值换掉!
那如何将“哈哈哈”展示在视野中? —— js控制“代表页面的元素”整体移动即可。
这里有个“遮罩层效果”,按照传统的js实现肯定就要去找display了,再进一步可以用上面所说的“display动画效果”增强体验。 但是本文上面css代码中加了 pointer-events 属性:元素是否穿透;设置为none时就可以不用在意对应元素是否存在了(从事件上看此时有和没有一样了),也就不用控制display什么的,大大增强性能了有木有!
let right= document. querySelector ( ".right" ) ;
let box= document. querySelector ( ".box" ) ;
let mask= document. querySelector ( ".zb_mask" ) ;
right. onclick = function ( ) {
box. style. marginLeft= "-12rem" ;
mask. style. cssText+= "opacity: 1;pointer-events: all;"
}
mask. onclick = function ( ) {
box. style. marginLeft= "0" ;
mask. style. cssText+= "opacity: 0;pointer-events: none;"
}
最后,考虑到移动端页面展示的一些问题,比如:右侧留白问题、原生手势对页面整体的影响等,我们一般会在css中设置 html{max-width: 100vw;overflow-x: hidden;} 。如果你想要用户在移动端依然只能够通过点击弹出侧边栏,在这里我们可以在css中加上限制 —— 设置上方功能只有在PC端生效:
@media ( any-hover : none) {
.page_list {
overflow-x : hidden;
}
}
本文同步分享在 博客“行舟客”(CSDN)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划 ”,欢迎正在阅读的你也加入,一起分享。