学习Milligram官网的导航效果(下)

Published: 2016-01-21

Tags: CSS3

本文总阅读量

milligram

这个点击并且显示菜单的效果还不错,值的学习一下,看控制台的输出,循环点击“Docs”与“Support”,可看见是.navigation-link行下添加有一个div层,通过给这个div层添加删除class来实现显示效果

按照网站的样式,修改之前的index.js文件,在链接a兄弟位置添加div,保存链接内容等。至于样式最后进行说明

<ul class="navigation-list float-right">
  <li class="navigation-item">
    <a class="navigation-link" href="#popover-grid" data-popover>Docs</a>
    <div class="popover" id="popover-grid">
      <ul class="popover-list">
        <li class="popover-item"><a class="popover-link" href="#getting-started" title="Getting Started">Getting Started</a></li>
        <li class="popover-item"><a class="popover-link" href="#hello" title="Hello">Hello</a></li>
        <li class="popover-item"><a class="popover-link" href="#world" title="World">World</a></li>
      </ul>
    </div>
  </li>
  <li class="navigation-item">
    <a class="navigation-link" href="#popover-support" data-popover>Links</a>
    <div class="popover" id="popover-support">
      <ul class="popover-list">
        <li class="popover-item"><a class="popover-link" href="https://www.google.com/" title="Google">Google</a></li>
        <li class="popover-item"><a class="popover-link" href="https://www.twitter.com/" title="Twitter">Twitter</a></li>
        <li class="popover-item"><a class="popover-link" href="http://www.gimp.org" title="GIMP">GIMP</a></li>
      </ul>
    </div>
  </li>
</ul>

milligram

整个网页的内容没什么冗余,整个页面也只在尾部引用了一个不大的,未经加密的js文件 点我查看

先看一下js的事件部分,内容如下(相关部分) :

;(function() {

    'use strict';

    var i,
        $popoverLinks   = document.querySelectorAll('[data-popover]'),
        $popovers           = document.querySelectorAll('.popover');

    function init() {
        for (i = 0; i < $popoverLinks.length; i++) $popoverLinks[i].addEventListener('click', openPopover);
        document.addEventListener('click', closePopover); 
    }

    function closePopover(e) {
        for (i = 0; i < $popovers.length; i++) $popovers[i].classList.remove('popover-open');
    }

    function openPopover(e) {
        e.preventDefault();
        if (document.querySelector(this.getAttribute('href')).classList.contains('popover-open')) {
            document.querySelector(this.getAttribute('href')).classList.remove('popover-open');
        }
        else {
            closePopover();
            document.querySelector(this.getAttribute('href')).classList.add('popover-open');
        }
        e.stopImmediatePropagation();
    }

    init();

}());

之前最多的用到js事件的地方是onclick,写在html中,刚读过一篇文章,说这是一种高耦合的写法,正确的做法是全部写入js中,进行操作,讲解javascript事件非常的详尽,推荐阅读: 《JavaScript 和事件》- 于江水

上面的javascript代码意思还是挺清晰的,就是通过点击给div添加或者删除.popover-open,关于preventDefault取消默认行为和stopImmediatePropagation停止冒泡方法在上边给出的文章也都有介绍。并且在初始化的时候给document绑定click事件,这样当出现菜单时,点击其余地方菜单就关闭了

那么,重头戏来了,看看展开列表的css是怎么实现的

/* Popover
// –––––––––––––––––––––––––––––––––––––––––––––––––– */

.popover.popover-open {
    display: block;
}
.popover {
    background: #fff;
    border: .1rem solid #d1d1d1;
    border-radius: .4rem;
    display: none;
    left: 50%;
    min-width: 13.4rem;
    position: absolute;
    top: 94%;
    -webkit-filter: drop-shadow(0 0 .6rem rgba(0,0,0,.1));
    -moz-filter: drop-shadow(0 0 .6rem rgba(0,0,0,.1));
    filter: drop-shadow(0 0 .6rem rgba(0,0,0,.1));
    -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    transform: translateX(-50%);
}
.popover-item:first-child .popover-link:after, .popover-item:first-child .popover-link:before {
    bottom: 100%;
    left: 50%;
    border: solid transparent;
    content: ' ';
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}
.popover-item:first-child .popover-link:after {
    border-color: transparent;
    border-bottom-color: #fff;
    border-width: 1.0rem;
    margin-left: -1.0rem;
}
.popover-item:first-child .popover-link:before {
    border-color: rgba(238, 238, 238, 0);
    border-bottom-color: #d1d1d1;
    border-width: 1.1rem;
    margin-left: -1.1rem;
}
.popover-list {
    padding: 0;
    margin: 0;
    list-style: none;
}
.popover-item {
    padding: 0;
    margin: 0;
}
.popover-link {
    position: relative;
    color: #606c76;
    display: block;
    padding: .8rem 2.0rem;
    border-bottom: .1rem solid #d1d1d1;
    text-decoration: none;
    font-size: 1.2rem;
    text-align: center;
}
.popover-item:first-child .popover-link {
    border-radius: .4rem .4rem 0 0;
}
.popover-item:last-child .popover-link {
    border-radius: 0 0 .4rem .4rem;
    border-bottom-width: 0;
}
.popover-link:hover {
    color: #ffffff;
    background: #9b4dca;
}
.popover-link:hover, .popover-item:first-child .popover-link:hover:after {
    border-bottom-color: #9b4dca;
}

这个就不一点点手动写了,细节蛮多的,想要熟练掌握需要以后多用,多调试。

总结如下:

  • css制作的小三角形值得收藏,思路挺好。先用.popover-item:first-child .popover-link:after, .popover-item:first-child .popover-link:before完成两个三角形的共有属性,包括定位等,然后再在伪类before中制作一个1.1rem大小的三角形,设置颜色为灰色,在伪类after中制作一个1.0rem大小的三角形,这样,就会有0.1的灰色边框暴露出来。最后再用hover:after来设定当移动到第一个元素上时,对伪类after三角形也变换颜色,和第一个元素保持一致

  • 整个列表的位置定位,通过position设置为absolute绝对定位,在div的父元素设置position: relative;,否则它就根据document进行绝对定位了,关于position的定位,推荐一篇文章: 学习CSS布局 - position,关于使用position进行元素水平居中有个答案也挺不错的:left:50%和-50%的理解

  • 之前对于导航挺头痛的,拆开来学习一下确实收获蛮多,之后再学习点更加复杂,其它类别的导航。相信不久就可以灵活的设计自己的导航~