移动web顶部导航栏的制作小心得

之前一直涉及到的都是PC端的Web,现在要做微信公众号的时候,发现很多PC端的效果在手机上做起来是有一定的差别,要做很多兼容和调整的东西。现在来谈一谈这些天做顶部固定导航栏的小心得。
因为博客貌似会解析文本中写的html代码,影响代码展示效果,所以为了方便,很多时候代码可能使用的是截图,给大家造成不便,聊表歉意。
1.关于顶部固定导航栏
效果图如下:
移动web顶部导航栏的制作小心得_第1张图片
实现代码如下:


移动web顶部导航栏的制作小心得_第2张图片
移动web顶部导航栏的制作小心得_第3张图片


整体框架图如下图所示:
移动web顶部导航栏的制作小心得_第4张图片
现在让我们来看看css是怎么写的吧:
#nav{
  width:100%;
  margin:0px auto;
 top:0px;//设置导航栏距离浏览器顶部的位置,0px表示固定到浏览器顶部,之所以position不用fixed,是因为有一些手机的内置浏览器不支持,会出现页面元素位置不对的问题
  left:0px;
  position:relative;
  z-index:9999;
  text-align:center;
  background-color: #f1f1f1;
  color:#333;
}
//左侧筛选框的样式(左侧是用的二级导航菜单,class=“dorpdown-layer”之后的样式都是第二级菜单的样式,可以不看)
#categorys-2014 {
    float: left;
    height: 44px;
    overflow: visible;
    position:relative;
    width: 50%;
    z-index: 10;
}
#categorys-2014 .dt a {
color: #999;
display: inline-block;
font: 400 15px/44px "microsoft yahei";
height: 100%;
text-decoration: none;
background-attachment: scroll;
background-color: #fff;
background-image: none;
background-repeat: repeat;
background-position: 0 0;
border: 1px solid #ddd;
width:100%;
}
#categorys-2014 .dd {
background-attachment: scroll;
background-color: #f1f1f1;
background-image: none;
background-repeat: repeat;
background-position: 0 0;
}
#categorys-2014 .dd-inner .item {
color: #999;
height: 43px;
position: relative;
z-index: 1;
text-indent:10px;
margin: 0;
    padding: 0;
}
#categorys-2014 .dd-inner .item a {
    color: #999;
}
#categorys-2014 .dd-inner h3 {
    font-family: "microsoftyahei";
    font-size: 14px;
    font-weight: 400;
    height: 51px;
text-indent:10px;
    line-height: 51px;
    padding: 0 10px;
    position:absolute;
    z-index: 2;
margin: 0;
    padding: 0;
}

#categorys-2014 .dd-inner .hover {
    background: #fff nonerepeat scroll 0 0;
   color:#333!important;
}

#categorys-2014 .dorpdown-layer {
    background: #fff nonerepeat scroll 0 0;
    border: 1px solid#ddd;
    display: none;
    width:100%;
    left: 100%;
    overflow: hidden;
    position:absolute;
    top: 46px;
}
#categorys-2014 .dorpdown-layer .hover {
    display:inline-block;
}
#categorys-2014 .item-sub {
    display: none;
    overflow: hidden;
    width:100%;
}
#categorys-2014 .item-sub::after {
    clear: both;
    content: ".";
    display:inline-block;
    height: 0;
}
.item_dd{
width:100%;
text-align:left;
}

.item_dd .ed{
color: #999;
    height: 43px;
    position:relative;
    z-index: 1;
    text-indent: 10px;
    margin: 0;
    padding: 0;
border-bottom: 1px solid #ddd;
}

.item_dd .ed h3{
line-height: 51px;
font-size: 14px;
font-family: microsoft yahei;
}
.item_dd .ed a {
    color: #999;
} 
//右侧排序样式
#right{
float: left;
    height: 44px;
    overflow: visible;
    position:relative;
    width: 50%;
}

#right .drt a{
color: #999;
display: inline-block;
font: 400 15px/44px "microsoft yahei";
height: 100%;
text-decoration: none;
background-attachment: scroll;
background-color: #fff;
background-image: none;
background-repeat: repeat;
background-position: 0 0;
border: 1px solid #dddddd;
width:100%;
}

#right .drd{
background-attachment: scroll;
background-color: #f1f1f1;
background-image: none;
background-repeat: repeat;
background-position: 0 0;
}

#right .drd .drw {
color: #999;
height: 43px;
position: relative;
z-index: 1;
text-indent:10px;
margin: 0;
    padding: 0;
}
#right .drd .drw a {
    color: #999;
}
#right .drd .drw h3 {
    font-family: "microsoftyahei";
    font-size: 14px;
    font-weight: 400;
    height: 51px;
text-indent:10px;
    line-height: 51px;
    padding: 0 10px;
    position:absolute;
margin: 0;
    padding: 0;
}
//搜索框 的样式
.flexsearch--wrapper {
height: auto;
width: auto;
max-width: 100%;
overflow: hidden;
background: transparent;
margin: 0;
position: static;
}
.flexsearch--form {
overflow: hidden;
position: relative;
}
.flexsearch--input-wrapper {
padding: 10px 13px 10px 13px;
overflow: hidden;
}

.flexsearch--input {
  width: 100%;
}

.flexsearch {
   
}

.flexsearch--input {
    -webkit-box-sizing:content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
border-color: #bcbcbc;
    border-radius:35px;
    border-style:solid;
border-width: 1px;
    margin: auto;
    color: #333;
font: 400 15px/35px "microsoft yahei";
-webkit-appearance: none;
-moz-appearance: none;
}

.flexsearch--input:focus {
  outline: none;
  border-color: #333;
}

.flexsearch--input:focus.flexsearch--submit {
  color: #333; 
}

.flexsearch--submit:hover {
  color: #333;
  cursor: pointer;
}

::-webkit-input-placeholder {
color: #888;  
}

input:-moz-placeholder {
  color: #888
}

@font-face {
  font-family: 'iconfont';
  src:url('//at.alicdn.com/t/font_1477547042_4651453.eot');
  src:url('//at.alicdn.com/t/font_1477547042_4651453.eot?#iefix')format('embedded-opentype'),
 url('//at.alicdn.com/t/font_1477547042_4651453.woff')format('woff'),
 url('//at.alicdn.com/t/font_1477547042_4651453.ttf')format('truetype'),
 url('//at.alicdn.com/t/font_1477547042_4651453.svg#iconfont')format('svg');
}
                 
.iconfont{
font-family:"iconfont";
font-size:16px;
font-style:normal;
-webkit-font-smoothing: antialiased;
   -webkit-text-stroke-width: 0.2px;
    -moz-osx-font-smoothing:grayscale; 
    padding-left:5px
}

//遮罩层的css样式
#bg{ 
display: none;
position: absolute;  
top: 0%;  
left: 0%;  
width: 100%;  
height: 100%;  
background-color: #333;  
z-index:1001;  
-moz-opacity: 0.7;  
opacity:.70;  
filter: alpha(opacity=70);
}

//当发生点击事件时的css变化
.abackimg{
color:#fac611!important;
}

.supabackimg{
background: #fff none repeat scroll 0 0;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}

.select{
color:#333!important;
}



到现在静态页面就完成了。
该处理鼠标的hover事件了,到这里我想就有人会问了,hover事件在PC端是很好用的,但是在移动端触屏设备上hover就不好用了,为什么还要用hover。在这里要解释一下,PC端的hover到移动端的时候就会转变为触屏的tap事件,对hover事件的处理也会自动转化为tap事件的处理。相对于click事件的默认延时300s响应,我觉得这样更合适一点。(有更好的意见欢迎指点交流)
下面贴上的是部分JS代码:


移动web顶部导航栏的制作小心得_第5张图片
这样,一个完整的固定导航栏就做好了。
在文章的最后我来解释一下为什么我要在使用顶部导航栏的时候加上遮罩层。
因为导航栏被点开之后,如果不选择内容,那么你会发现页面会发生一件很有意思的时间,导航栏不会自动收回去,但是页面还能进行滚动,加载新的内容,这样的用户会很不好,你需要对页面导航栏以外的内容进行点击才能收回导航栏展开的部分,但是若是你的页面除了导航栏以外的地方都是可点击区域,就会很尴尬了,每次一收回导航栏页面就跳走了。这个时候我们需要设置一个遮罩层,隔离开导航栏展开部分和页面内容,在这里我们要理解一个概念--什么叫点击穿透事件,发生点击穿透事件的原因是什么。

在我们点击导航栏展开部分以外的遮罩层时,touchend首先触发tap,弹出层和遮罩就被隐藏了。touchend后继续等待300ms发现没有其他行为了,则继续触发click,由于这时弹出层已经消失,所以当前click事件的target就在底层元素上,于是就alert内容。整个事件触发过程为touchend -> tap -> click。

而由于click事件的滞后性(300ms),在这300ms内上层元素隐藏或消失了,下层同样位置的DOM元素触发了click事件(如果是input框则会触发focus事件),看起来就像点击的target“穿透”到下层去了。

既然知道了为什么产生的原因了,那么如何解决穿透呢?

穿透的解决办法

1. 遮挡

由于 click事件的滞后性,在这段时间内原来点击的元素消失了,于是便“穿透”了。因此我们顺着这个思路就想到,可以给元素的消失做一个fade效果,类似jQuery里的fadeOut,并设置动画duration大于300ms,这样当延迟的click 触发时,就不会“穿透”到下方的元素了。

同样的道理,不用延时动画,我们还可以动态地在触摸位置生成一个透明的元素,这样当上层元素消失而延迟的click来到时,它点击到的是那个透明的元素,也不会“穿透”到底下。在一定的timeout后再将生成的透明元素移除。

2. pointer-events

pointer-events是CSS3中的属性,它有很多取值,有用的主要是autonone,其他属性值为SVG服务。

取值 含义
auto 效果和没有定义 pointer-events 属性相同,鼠标不会穿透当前层。
none 元素不再是鼠标事件的目标,鼠标不再监听当前层而去监听下面的层中的元素。但是如果它的子元素设置了pointer-events为其它值,比如auto,鼠标还是会监听这个子元素的。

文中用的就是这一种解决方法。

3. fastclick

使用fastclick库,其实现思路是,取消 click 事件(参看源码 164-173 行),用 touchend 模拟快速点击行为(参看源码 521-610 行)。

FastClick.attach(document.body);

从此所有点击事件都使用click,不会出现“穿透”的问题,并且没有300ms的延迟。

到这里,这篇文章就完了,要是大家有什么更好的方法,也可以和我交流一下哦,感激不尽。


你可能感兴趣的:(移动web)