跨终端电商平台的实现之移动端详情页多窗口切换(选项卡)效果实现
在移动端的商品详情页涉及多个内容切换的问题,这里使用选项卡设计方式,使用选项卡的设计是各大主流电商平台所采用主要形式,例如淘宝和京东。简单的选项卡实现起来比较容易,只要监听选项按钮并控制相应内容的现实与隐藏。如果只是单纯的显示和隐藏的话,对于用户的体验不好。所以改单纯的显示与隐藏为滑动的效果,要实现滑动的效果就需要满足以下几个条件:
1.所有选项卡都应该包含在同一个元素之中,通过父元素位置的改变来达到滑动的效果;
2.由于各个选项卡的高度不一致,所以应该在滑动结束后实时动态的去改变父元素的高度。选项卡实现效果图:
实现的思路是构造一个基础函数用于实现父元素的移动,传入的参数有移动的方向以及移动的距离。本设计中该选项卡有三个选项,所以移动的方向有两个而移动距离有两种情况,分别是滑动一屏和滑动两个屏幕的长度,同样这里为了兼容各个不同的设备采用的是相对单位,一个屏幕的宽度等于10rem。然后构造第二个函数,根据传入的现在选项卡的id和要显示选项卡的id,在条件语句中执行相应的滑动函数。除了这两个函数之外还需要添加相关的监听事件来确定起始位置与目标位置。
首先通过HTML代码,看下页面的结构是怎样的:
//页面的头部,包含三个按钮
div.header
span#header-info.header-focus 基本信息
span#header-more 商品详情
span#header-comment 评价1734
//页面的中部,包含的是具体的三个板块,每次只显示某个板块
//选项卡功能就是通过页面头部按钮和中部内容互动实现
div.middle-outer
div.middle
//基本信息模块
div.info
div.piclist-outer
div.piclist-inner
each singleBig in gmainImgs
img(src='#{singleBig}' alt='slide img')
//商品详情模块
div.more
span 商品图片
div.more-wrapper
each singDetailImg in gdetailImgs
img(src="#{singDetailImg}" alt="")
//商品评论模块
div.comment
div.comment-keyword
span.keywords-selected 全部
span 追加(569)
span 有图(453)
span 鞋子不错(452)
span 做工一般(12)
span 舒适度不错(659)
//页面的底部
div.footer
div.footer-iconlist
a(href='javascript:;').footer-iconlist-link
span.glyphicon.glyphicon-user
span.footer-iconList-txt 客服
a(href='javascript:;').footer-iconlist-link
span.glyphicon.glyphicon-star-empty
span.footer-iconList-txt 收藏
a(href='/mshopcart').footer-iconlist-link
span.glyphicon.glyphicon-shopping-cart
span.footer-iconList-txt 购物车
div#footer-btns
a(href='javascript:;').footer-btn.footer-btn-addToCart 加入购物车
a(href='javascript:;').footer-btn.footer-btn-buyNow 立即购买
div.masker
span.masker-text 加入购物车成功
span.masker-sign
span.glyphicon.glyphicon-ok
具体的JS代码为:
//关键的两个函数,slide和move,slide确定移动的方向和距离,move负责具体的移动
//在此函数中使用switch语句来进行判断可以使用更加简洁的代码,直接调用函数move并传入dis值,需要简单调整下move函数的实现
//根据起始的位置以及最终的位置来调用函数move
function slide(nowPosId,nextPosId) {
//获取当前点击的头部按钮的id值与此前选中头部按钮的id值
//使用两者相减得到差值
var dis=nextPosId - nowPosId
//使用switch语句根据不同的差值执行不同的调用
switch(dis){
case 1:
//slide to left 10rem
//如果差值为1则向左滑动一屏的距离
move(-1 , screenWidth)
break
case -1:
//slide to right 10rem
//如果差值为-1则右滑动一屏距离
move(1 , screenWidth)
break
case 2:
//slide to left 20rem
//如果差值为2则向左滑动两屏距离
move(-1 , 2 * screenWidth)
break
case -2:
//slide to right 20rem
//如果差值为-2则向右滑动两屏距离
move(1 , 2 * screenWidth)
break
}
}
//执行具体的元素移动的函数,direc表示方向,-1表示向左滑动,1表示向右滑动
function move( direc , move_lenth) {
//用于记录移动的距离,当移动距离达到参数时停止计时器
var move_dis=0
//计时器的执行间隔时间
var move_time=20
//获取父元素的left值
var now_css_left=parseInt($('.middle').css('left'))
//开始执行计时器,使用一个作用于限于函数的变量来保存计时器对象
var timer=setInterval(function () {
//计算得到一次执行中的left值,当direc带有正负的信息可以决定移动的方向
now_css_left += direc * setpmove
//计算累计移动距离
move_dis +=setpmove
//设置父元素的left值
$('.middle').css('left',now_css_left + 'px')
//当移动完毕时,根据被点击的按钮来设置父元素的高度
if (Math.abs(move_dis - move_lenth) < 0.001 ) {
clearInterval(timer)
switch(focus_id){
case(1):
$('.middle').css('left','0rem').css("height" , infoH)
$(".middle-outer").css("height" , infoH)
console.log($(".middle-outer").css("height"))
break
case(2):
$('.middle').css('left','-10rem').css("height" , moreH)
$(".middle-outer").css("height" , moreH)
console.log($(".middle-outer").css("height"))
break
case(3):
$('.middle').css('left','-20rem').css("height" , commentH)
$(".middle-outer").css("height" , commentH)
console.log($(".middle-outer").css("height"))
break
default:
break
}
//将页面设置到最顶部,因为子元素高度不统一的缘故
window.scrollTo(0,0)
}
},move_time)//end timer
}//end func move
//点击的监听事件
//点击头部标题“基本信息”的监听事件
$('#header-info').click(function () {
//header_focus_item变量保存的是此时聚焦的选项卡按钮的标题,
//若点击此时显示选项卡自己的按钮,则不执行任何操作
if (header_focus_item==$(this).attr('id')) {
return
}
//clickbtn变量保存的点击按钮的序号,“基本信息”为1,“商品详情”为2,“评价”为3
clickbtn=1
//调用slide函数,传入的值为当前的选项卡id以及目标的id
slide(focus_id,clickbtn)
focus_id=1
//改变此按钮的样式,是用户能够清楚了解此时查看的是哪一个选项卡
$(this).addClass('header-focus')
//改变此前选中选项卡对应按钮的样式,使其成为普通选项卡按钮
$("#"+header_focus_item).removeClass('header-focus')
header_focus_item='header-info'
})
//点击头部“商品详情”的监听事件,执行的操作和点击“基本信息”类同
$('#header-more').click(function () {
if (header_focus_item==$(this).attr('id')) {
return
}
clickbtn=2
slide(focus_id,clickbtn)
focus_id=2
$(this).addClass('header-focus')
$("#"+header_focus_item).removeClass('header-focus')
header_focus_item='header-more'
})
//点击头部“评价”的监听事件,执行的操作和点击“基本信息”类同
$('#header-comment').click(function () {
if (header_focus_item==$(this).attr('id')) {
return
}
clickbtn=3
slide(focus_id,clickbtn)
focus_id=3
$(this).addClass('header-focus')
$("#"+header_focus_item).removeClass('header-focus')
header_focus_item='header-comment'
})
查看完整项目可以去我的GitHub,欢迎大家的下载、提问和关注哈。