本篇文章给大家带来的内容是关于如何使用纯css实现手机通讯录的效果,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

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

如何使用纯css实现手机通讯录的效果

  1. 首字母吸顶

  2. 快速定位

下面我们来实现一下

页面结构

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

<div class="con">     <!--联系人列表-->     <div class="contacts" id="contacts">         <dl>A</dt>         <dt>a1</dt>         <dt>a2</dt>         <dl>B</dt>         <dt>b1</dt>         <dt>b2</dt>         ...     </div>     <!--导航列表-->     <div class="index" id="index">         <a>A</a>         <a>B</a>     </div> </div>

然后加点样式

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 的元素。

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

如何使用纯css实现手机通讯录的效果

给.contacts dt加上position:sticky

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

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

实现快速定位效果

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

具体做法就是

<a href='#A'></a> ... ...  <div id='A'></div>

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

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

<div class="con">     <!--联系人列表-->     <div class="contacts" id="contacts">         <dl id='A'>A</dt>         <dt>a1</dt>         <dt>a2</dt>         <dl id='B'>B</dt>         <dt>b1</dt>         <dt>b2</dt>         ...     </div>     <!--导航列表-->     <div class="index" id="index">         <a href='#A'>A</a>         <a href='#B'>B</a>     </div> </div>

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

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

如何使用纯css实现手机通讯录的效果

这是什么问题呢?

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

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

发现问题就要解决问题

快速定位效果修复

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

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

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

<div class="contacts" id="contacts">         <dl>A</dt>         <dl class="stikcy-fix" id='A'></dt>         <dt>a1</dt>         <dt>a2</dt>         <dl>B</dt>         <dl class="stikcy-fix" id='B'></dl>         <dt>b1</dt>         <dt>b2</dt>         ...     </div>

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

如下

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

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

其他细节

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

如何使用纯css实现手机通讯录的效果

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

具体实现如下

.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属性

<!--导航列表--> <div class="index" id="index">     <a href='#A' data-type='A'>A</a>     <a href='#B' data-type='B'>B</a> </div>

其次,实际项目中,我们需要用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 += '<dl><dt>'+el.type+'</dt><dt class="stikcy-fix" id='+el.type+'></dt>';     index_html += '<a href="#'+el.type+'" data-type='+el.type+'>'+el.type+'</a>';     el.user.forEach(d=>{         contacts_html+='<dd>'+d.name+'</dd>';     })     contacts_html+='</dl>' }) indexs.innerHTML = index_html; contacts.innerHTML = contacts_html;

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

一些不足

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

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

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

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

标签
DT素材网

DT素材网

148

0

0

( 此人很懒并没有留下什么~~ )