博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
纯css实现手机通讯录
阅读量:6496 次
发布时间:2019-06-24

本文共 7444 字,大约阅读时间需要 24 分钟。

我们经常在手机上看到通讯录列表,这类布局一般有两个显著的效果

20181016202731.png

  1. 首字母吸顶
  2. 快速定位

下面我们来实现一下

页面结构

这里页面结构很简单,就是两个列表

A
a1
a2
B
b1
b2
...
A
B

然后加点样式

html,body{    margin: 0;    height: 100%;    padding: 0;}dl,dd{    margin: 0;}.con{    position: relative;    height: 100%;    overflow-x: hidden;}.index{    position: absolute;    right: 0;    top: 0;    bottom: 0;    display: flex;    flex-direction: column;    justify-content: center;}.index a{    display: block;    width: 30px;    height: 30px;    text-align: center;    line-height: 30px;    border-radius: 50%;    background: cornflowerblue;    text-decoration: none;    color: #fff;    outline: 0;    margin: 5px;}.contacts{    height: 100%;    background: #fff;    overflow: auto;    line-height: 2em;}.contacts dt{    background: bisque;    font-size: 1.5rem;    color:cornflowerblue;    height: 2em;    line-height: 2em;    padding: 0 10px;}.contacts dd{    padding: 0 10px;    display: block;    cursor: pointer;}

这样就可以看到布局了

实现吸顶效果

吸顶效果其实很简单,只要用到css中的新属性position:sticky就可以了

粘性定位元素(stickily positioned element)是计算后位置属性为 sticky 的元素。

兼容性还不错,至少在移动端可以放心使用

20181016204441.png

.contacts dt加上position:sticky

.contacts dt{    /*添加如下属性*/    position: sticky;    top: 0;}

这样就实现了每个类目吸顶效果

实现快速定位效果

如果不用js,那么可采用href锚点的方式来实现定位

具体做法就是

......

如果整个页面是可以滚动的,那么只要点击a,那么页面就会迅速跳转到id=A的元素上

现在对我们的页面添加一些herfid

A
a1
a2
B
b1
b2
...
A
B

点击右侧的导航按钮,页面就可以快速定位了

等等,好像还有些问题,当往回跳转时,发现并没有完全展开,比如像调回A,结果虽然A标签出来了,但是,A下面的列表却没有出来

20181016205557.png

这是什么问题呢?

经过多次的研究,发现是position:sticky搞的鬼!

当往上定位的时候,我们通过href定位过去,定位的依据是到该元素第一次可见的位置,此时虽然该元素空压机了,但是下面的元素没有展示出来,所以就造成了这样的问题

发现问题就要解决问题

快速定位效果修复

其实我们想要定位的还可以是A下面的第一个列表元素,但是又不能是该元素,因为如果是第一代元素,当跳转的时候就会被上面的A标签遮住。

所以我们在两者之间再插入一个标签,用于定位

如下,添加了<dl class="stikcy-fix"></dt>

A
a1
a2
B
b1
b2
...

如果直接放在这里肯定会占空间,所以我们把他向上位移,然后设置不可见,使该元素刚好覆盖在原标签位置

如下

.contacts .stikcy-fix{    position: static;    visibility: hidden;    margin-top: -2em;}

现在看看,是不是完美跳转了?

其他细节

通常我们在选择右侧索引时,页面中间会出现一个大写的字母

20181017093614.png

这个如果用css实现也比较简单,用到伪元素的content:attr()就可以了,在之前的文章中也讲到过

具体实现如下

.index a:active:after{    content: attr(data-type);    position: fixed;    left: 50%;    top: 50%;    width: 100px;    height: 100px;    border-radius: 5px;    text-align: center;    line-height: 100px;    font-size: 50px;    transform: translate(-50%,-50%);    background: rgba(0,0,0,.5);}

这里用到了content: attr(data-type),所以a上面要有一个data-type属性

A
B

其次,实际项目中,我们需要用js来生成这些列表

假定我们要求的数据如下

var data = [        {            'type':'A',            'user':[                {                    name:'a1'                },                {                    name:'a2'                },                {                    name:'a3'                },                {                    name:'a1'                },                {                    name:'a2'                },                {                    name:'a3'                },                {                    name:'a3'                },                {                    name:'a1'                },                {                    name:'a2'                },                {                    name:'a3'                },            ]        },        {            'type':'B',            'user':[                {                    name:'b1'                },                {                    name:'b2'                },                {                    name:'b3'                },                {                    name:'b1'                },                {                    name:'b2'                },                {                    name:'b3'                },                {                    name:'b3'                },                {                    name:'b1'                },                {                    name:'b2'                },                {                    name:'b3'                },            ]        },        {            'type':'C',            'user':[                {                    name:'c1'                },                {                    name:'c2'                },                {                    name:'c3'                },                {                    name:'c1'                },                {                    name:'c2'                },                {                    name:'c3'                },                {                    name:'c3'                },                {                    name:'c1'                },                {                    name:'c2'                },                {                    name:'c3'                },            ]        },        {            'type':'D',            'user':[                {                    name:'d1'                },                {                    name:'d2'                },                {                    name:'d3'                },                {                    name:'d1'                },                {                    name:'d2'                },                {                    name:'d3'                },                {                    name:'d3'                },                {                    name:'d1'                },                {                    name:'d2'                },                {                    name:'d3'                },            ]        },        {            'type':'E',            'user':[                {                    name:'e1'                },                {                    name:'e2'                },                {                    name:'e3'                },                {                    name:'e1'                },                {                    name:'e2'                },                {                    name:'e3'                },                {                    name:'e3'                },                {                    name:'e1'                },                {                    name:'e2'                },                {                    name:'e3'                },            ]        }    ]

这种格式的数据可以要求后端返回,或者直接前端改造都行

然后对数据进行循环遍历即可

var indexs = document.getElementById('index');var contacts = document.getElementById('contacts');var index_html = '';var contacts_html = '';data.forEach(el=>{    contacts_html += '
'+el.type+'
'; index_html += '
'+el.type+''; el.user.forEach(d=>{ contacts_html+='
'+d.name+'
'; }) contacts_html+='
'})indexs.innerHTML = index_html;contacts.innerHTML = contacts_html;

这部分js只是生成布局,没有任何功能上的逻辑

一些不足

虽然通过锚点实现列表的快速定位,但是此时浏览器的地址栏会加上#A这样的标识,一不好看,二在使用浏览器默认的返回时会把这些标识全部走一遍,不太方便。

还有一个问题,在滚动列表的时候,没法做到右侧索引当前类别高亮显示,同时右侧索引也不支持滑动快速定位。

这些细节问题也只能通过js来修复了。

不过要是一个简单的小项目,没那么多要求的话,纯css还是能很好的适用的,性能上绝对要比通过js滚动监听强上好多倍,而且引用方便,只要数据生成了就可以直接使用^^

转载地址:http://uauyo.baihongyu.com/

你可能感兴趣的文章
Black and White
查看>>
静态变量和实例变量的区别
查看>>
晨跑【最小费用最大流】
查看>>
景点中心 C组模拟赛
查看>>
iOS国际化(多语言设置)
查看>>
bzoj 2733 平衡树启发式合并
查看>>
sublime简书安装配置
查看>>
爱上MVC~Web.Config的Debug和Release版本介绍
查看>>
条款03 尽可能使用const
查看>>
【转】那些年我们一起清除过的浮动
查看>>
python__高级 : 动态添加 对象属性, 类属性, 对象实例方法, 类静态方法, 类方法...
查看>>
【每天一道算法题】时间复杂度为O(n)的排序
查看>>
NLog的介绍使用
查看>>
Haproxy+Rabbitmq中的问题
查看>>
字符串变量小议
查看>>
232. Implement Queue using Stacks
查看>>
Poj(1469),二分图最大匹配
查看>>
和菜鸟一起学linux之V4L2摄像头应用流程【转】
查看>>
spin_lock、spin_lock_irq、spin_lock_irqsave区别【转】
查看>>
删除 mac 垃圾桶内清除不掉的文件
查看>>