2

在移动端的商品详情页涉及多个内容切换的问题,这里使用选项卡设计方式,使用选项卡的设计是各大主流电商平台所采用主要形式,例如淘宝和京东。简单的选项卡实现起来比较容易,只要监听选项按钮并控制相应内容的现实与隐藏。如果只是单纯的显示和隐藏的话,对于用户的体验不好。所以改单纯的显示与隐藏为滑动的效果,要实现滑动的效果就需要满足以下几个条件:
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,欢迎大家的下载、提问和关注哈。


小铀蔻德尔
201 声望3 粉丝

前端工程师