微商城详情页H5效果

这个效果是仿寺库APP的效果。

CSS

商品图

这个比较好说,向上滑动到一定阶段触发动画, 商品图变小,采用的是CSS3的translateZ() perspective 实现,当然也可以通过scale()和设置外层div宽高实现,用perspective是为了顺便实现加入购物车按钮3D翻转的效果。
颜色变灰,则是 filter:grayscale(),最后消失则是 opacity,最后的这个消失效果是个兼容iOS下图片闪烁的处理,后面再谈这个兼容问题。

商品图是用了swipe.js滑动。

1
2
3
4
5
6
7
<div class="goods-img" id="slider" style="visibility: visible; opacity: 1;">
<ul style="width: 1032.56px;">
<li><img src="" alt=""></li>
<li><img src="" alt=""></li>
<li><img src="" alt=""></li>
</ul>
</div>

详情介绍部分

一直居于底部,高度发生变化,并且是可滚动查看内容的。动画效果,主要是改变容器的height,并且绝对定位,居于底部,position:absolute;, 为了滚动, 加了属性 overflow:scroll。 一开始通过JS算出总高度和商品图高度,得到详情部分的初始高度。touchstart记录初始位置, touchmove则记录即时位置,
计算出商品图变小的比例和详情部分高度的变化。 touchendtouchcancel的时候,位移小则回复原位,大于50则向上展开。
购物车的图标的动画效果,在iOS下会使商品图-详情部分-购物车图标三者层级混乱闪烁,-webkit-backface-visibility:hidden无效,商品图隐藏可以规避这个问题。

初始布局, 高度是JS计算出来添加的, overflow:hidden 处理。

1
2
3
4
5
6
7
8
9
10
11
#main .goods-info {
overflow: hidden;
position: absolute;
margin: 0 0.27778rem;
width: 9.44444rem;
left: 0;
z-index: 2;
}

<div class="goods-info" style="overflow: hidden; transform: translateY(-10px); height: 313px;">
</div>

动画后, translateY向上移位, 高度变化, 并增加 overlfow:scroll, 让内容能滚动。

1
2
3
4
css:
overflow: scroll;
transform: translateY(-289px);
height: 592px;

JS

JS的坑。。
1 Android下, touchmove 事件只触发一次,不能实时触发,导致不能计算高度变化和图片缩小, 然后采用了 event.preventDefault() 解决;
2 preventDefault阻止了默认,导致按钮和<a href>无效。 打补丁,添加event.target判断;
3 与click事件的分辨,click过程是touchstart->touchend->click的触发顺序, 触发touchmove,则标记不是click事件;
4 touchcancel, 一开始的console没显示出触发touchcancel, 就忽略了~~ 结果后面发现bug,touchend事件的尾处理失效,导致动画失效,touchcancel 加上尾处理解决;

代码如下:

  • touchmove的兼容,用e.preventDefault();来处理
  • if (e.target.className.split(" ").indexOf("selt") >= 0) isPrevent = false; 这段默认链接补丁,用了变量保存, 需要在DOM中添加class .selt
  • isTouchMove处理坑3
  • isPrevent = true; isTouchMove = false; 加上尾
  • direction 是一个保存方向的变量,用户使详情部分能够下滑还原
  • _animate 是滑动的动画处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
goodsinfo.on('touchstart', function(e){
touchsY = e.touches[0].pageY;
if (e.target.className.split(" ").indexOf("selt") >= 0)
isPrevent = false;
if ( !direction && isPrevent){
e.preventDefault();
}
});
goodsinfo.on('touchmove', function(e){
isTouchMove = true;
touchmY = e.touches[0].pageY;
moveY = touchmY - touchsY;
if ( direction === false && moveY < 0 ) //向上滑动
move(moveY);
if ( direction === true && goodsinfo.scrollTop() <= 0 && moveY > 2 ){
direction = false;
_animate(0);
}
if ( !direction && isPrevent){
e.preventDefault();
}
});
goodsinfo.on('touchend', function(e){
if ( isPrevent ){
if ( direction === true || isTouchMove === false ) //向下 不处理
return false;
toucheY = touchmY;
var moveUp = touchsY - toucheY;
if ( moveUp > 20 && direction === false ){
direction = true;
_animate(imgHeight-windowWidth/5);
}
else{
direction = false;
_animate(0);
}
}
isPrevent = true;
isTouchMove = false;
});

goodsinfo.on('touchcancel', function(e){ //touchcancel ,有时候touchend 不触发, 初始化 isPrevent isTouchMove
isPrevent = true;
isTouchMove = false;
});