本篇文章给大家带来的内容是关于如何使用纯css实现手机通讯录的效果,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
我们经常在手机上看到通讯录列表,这类布局一般有两个显著的效果
首字母吸顶
快速定位
下面我们来实现一下
页面结构
这里页面结构很简单,就是两个列表
<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 的元素。兼容性还不错,至少在移动端可以放心使用
给.contacts dt加上position:sticky
.contacts dt{ /*添加如下属性*/ position: sticky; top: 0;}
这样就实现了每个类目吸顶效果
实现快速定位效果
如果不用js,那么可采用href锚点的方式来实现定位
具体做法就是
<a href='#a'></a>......<div id='a'></div>
如果整个页面是可以滚动的,那么只要点击a,那么页面就会迅速跳转到id=a的元素上
现在对我们的页面添加一些herf和id
<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下面的列表却没有出来
这是什么问题呢?
经过多次的研究,发现是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实现也比较简单,用到伪元素的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滚动监听强上好多倍,而且引用方便,只要数据生成了就可以直接使用
以上就是如何使用纯css实现手机通讯录的效果的详细内容。