抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

设计了一个标签页,包括选中的标签和待选的标签。
待选标签数量不定,屏幕宽度也不定,所以承载的地方高度不定。
希望实现一个盖住待选标签的盖子,能上下滑动,完全盖住待选标签或者露出来

前言

在做 6657 超级大爆的时候,设计了一个标签选择来筛选分类的页面。
标签分为已选和未选,然后下面的具体显示内容作为一个盖子盖住未选标签,盖子可以完全盖住或者完全露出来

大概如原型图所示
滑盖未划开,完全盖住待选:
sb6657_prototype

滑盖划开,完全露出待选:
sb6657_prototype

难点在于标签数量不定,屏幕宽度不定导致的换行不定,所以未选标签部分的高度不定
那么上面的盖子完全盖住或者露出移动的距离就不定了
并且我希望有过渡动画,盖子很丝滑的盖住或者露出。

解决

纯 css 行不通

一开始想完全用 css 实现,想了半天,不定的话可以把待选和盖子放一个 div 里,
切换盖子绝对定位和普通定位的流式布局,来实现盖住或者完全露出

但是这么弄就没过渡动画了,只有某属性的直接变化才能做 translation 过渡

然后想的就是待选标签盒子高度从 0 和 auto 变化,里面东西不能露出外部,这样确实有过渡了,看起来可行
但是从内部撑开的 auto 高度没法直接设置,它数值不定弄不了,没有数据驱动的 vue 式方法可用,
并且不定的 auto 高度 css 过渡处理不了,css 过渡本质上只能处理固定数值变化

那么看来只能使用操纵 dom 的方式了

这么做的话完全就是原生 h5 的解决方案,我归类成 vue 单纯因为式写 vue 时候遇到的问题

操作 DOM 实现

DOM 有个scrollHeight属性,是内部元素实际所占高度。如果溢出或者内部被隐藏也是实际的高度。
那么获取装待选标签 div 的scrollHeight,用它和 0px 来回实时赋值 height,css 里写上过渡,就实现了丝滑的滑盖动画
意外挺简单

不过注意一下要把待选标签承载盒子的溢出设置为隐藏

大致实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="tags">
<div class="tag1" v-for="(item, index) in currentTags" :key="index"></div>
</div>
<div class="meme-and-tag">
<div class="more-tags" ref="moreTagsDom">
<div class="line"></div>
<div class="tag1" v-for="(item, index) in moreTags" :key="index"></div>
</div>
<div class="list">
<img class="handle" src="@/assets/icon/downArrow.png" @click="slideList" />
这里是显示的分类数据,反正这里就是当滑盖用
</div>
</div>
1
2
3
4
5
6
7
.more-tags {
height: 0;
display: flex;
flex-wrap: wrap;
overflow: hidden;
transition: all 0.6s;
}
1
2
3
4
5
6
7
8
9
10
const tagSelecting = ref<boolean>(false);
const moreTagsDom = ref<HTMLElement>() as Ref<HTMLElement>;
function slideList() {
if (tagSelecting.value) {
moreTagsDom.value.style.height = '0px';
} else {
moreTagsDom.value.style.height = `${moreTagsDom.value.scrollHeight}px`;
}
tagSelecting.value = !tagSelecting.value;
}

后话

自从写了小程序的 uni-app 之后,有点不敢操作 DOM 了,啥都想首先用 vue 式的数据驱动实现,毕竟小程序的 DOM 操纵是个残废,更多的时候完全用不了,只能不用,有种便秘拉不出来的感觉

还是浏览器的前端写着爽,api 又多又全,vue 实现不了的直接干原生 h5

评论