实现滚动时页面伸缩效果

  不知道怎么起这篇文章的标题才能表达出我实现的页面效果,

  项目背景:嵌在原生开发的APP中。

  上图给大家看一下

  

  左侧图片代表进入app时页面的展示效果,右侧为页面滑动时的效果。

  因为原生开发的APP有导航栏的,所以根据他们封装的抛出H5的API,将导航栏设置为透明色,这样才可以将原生开发的导航栏的背景色去掉。

  首先说一下整个页面的布局。

  因为这个布局我是用fixed定位写的,尤其是中间白色区域中顶部的标题Tab切换部分滑到顶部时固定。所以使用的页面的布局代码大致如下

<body>
     <div class="container">
    <header class="headBox">
      <ul class="headerList">
        <li class="header-item">
            <i class="indexIcon scan"></i>
            <p class="header-title">按钮一</p>
        </li>
        <li class="header-item">
          <i class="indexIcon authorze"></i>
          <p class="header-title">按钮二</p>
        </li>
        <li class="header-item">
            <i class="indexIcon lending"></i>
            <p class="header-title">按钮三</p>
        </li>
      </ul>
    </header>
    <section class="mainBox">
       <ul class="navList">
        <li class="nav-item actived">列表一</li>
        <li class="nav-item ">列表二</li>
        <li class="nav-item">列表三</li>
        </ul>
       <div class="" id="main">
        <div class="topBox">
          <div class="topMain">
            <!--合同列表-->
              <div class="contractList ">
                <div class="top">
                    <div class="search-box">搜索</div>
                    <div class="contract-nav">
                      <span class="nav-style actived">全部</span>
                       <span class="nav-style">状态一</span>
                       <span class="nav-style">状态二</span>
                    </div>
                </div>
                <div class="main">
                    <ul class="allContract list-style">
                        <!--有数据时-->
                        <li class="list-item">
                          <span class="contract-status">状态一</span>
                           <p class="contract-title">标题</p>
                          <div class="content">
                            <i class="contract-num"></i>
                            <p class="content-style">编码</p>
                           </div>
                          <div class="content">
                            <i class="contract-firm"></i>
                            <p class="content-style">公司名称</p>
                          </div>
                            <i class="dots"></i>
                            <div class="content">
                              <i class="contract-dept"></i>
                                   <p class="content-style">部门名称</p>
                            </div>
                        </li>
                        <li class="addMore">更多</li>
                    </ul>
                  </div>
                </div>
                </div>
              </div>
            <section class="lawCon">
                <div class="law-title">法务区域</div>
            </section>
        </div>    
    </section>    
  </div>    
</body>

 这个的这个container布局采用的是fixed定位,头部也是用的固定定位,这样整体的文档流中都是固定定位的。在主体内容区域中,由于滑到顶部时,nav导航栏要求是固定的,所以,将这部分的布局放在主体布局的顶部,滚动区域之外,这样js在监听页面滑动时,将整个的主体区域固定位置就可以了。

css样式如下:

*{
                margin:0;
                padding:0;
                list-style: none;
            }
            body{
                background: #EFEFF4;
            }
            .none{
                display:none;
            }
            .container{
                width:100%;
                height:100%;
                position:fixed;
                top:0;
                left:0;
            }
            .headBox{
                width:100%;
                height: 4rem;
                display: flex;
                background: #30A2FC;
                position: fixed;
                top:0;
                left:0;
            }
            .headerList{
                width:100%;
                display: flex;
                position:fixed;
                top:1.76rem;
                left:0;
            }
            .header-item{
                width:33.33%;
                text-align: center;
            }
            .header-item .indexIcon{
                display: block;
                width:.8rem;
                height:.8rem;
                margin:0 auto .3rem auto;
                
            }
            .header-item .scan{
                background: url(img/scan.png) no-repeat;
                background-size: 100%;
            }
            .header-item .authorze{
                background: url(img/authorize.png) no-repeat;
                background-size: 100%;
            }
            .header-item .lending{
                background: url(img/lending.png) no-repeat;
                background-size: 100%;
            }
            .header-item .header-title{
                font-size: .14rem;
                color:#FFFFFF;
            }
            .mainBox{
                width:100%;
                position:fixed;
                top:3.53rem;
                left:0;
                box-sizing: border-box;
                padding: 0 .16rem;
                background: transparent;
            }
             .navList{
                display: flex;
                padding-top: .49rem;
                background: #FFFFFF;
                border-top-left-radius: 10px;
                border-top-right-radius: 10px;
                
            }
             .navList .nav-item{
                width:33.33%;
                font-size: .32rem;
                color: #898989;
                text-align: center;
            }
             .navList .nav-item.actived{
                font-weight:500;
                color:#252525;    
            }
             .navList .nav-item.actived::after{
                content:"";
                display: block;
                width:58%;
                height:2px;
                background: #000000;
                margin:.2rem 21%;
            }
            .topBox{
                width:7.18rem;
                min-height: 7rem;
                background: #FFFFFF;
                border-bottom-left-radius: 10px;
                border-bottom-right-radius: 10px;
                box-sizing: border-box;
                box-shadow:0px 4px 4px 0px rgba(0, 0, 0, 0.1);
            }
        
            
            .contractList .search-box,
            .authorzeList .search-box{
                float:right;
                margin-right:.24rem;
                font-size: .24rem;
                color: #C2C2C2;
            }
            .contractList .search-box::after,
            .authorzeList .search-box::after{
                content:"" ;
                display: inline-block;
                width:.18rem;
                height: .18rem;
                border:1px solid #C6C6C6;
                transform: rotateZ(45deg);
                border-bottom-color: transparent;
                border-left-color: transparent;
                
            }
            .contractList .contract-nav{
                display: flex;
                width:66%;
                justify-content: space-around;
            }
            
            .contractList .contract-nav .nav-style{
                font-size: .28rem;
                color: #959595;
                font-weight:400;
            }
            .contractList .contract-nav .nav-style.actived{
                color: #2D8DF1;
            }
            .contractList .contract-nav .nav-style.actived::after{
                content:"";
                display: block;
                width:100%;
                height:2px;
                margin-top:.16rem;
                background: #2D8DF1;
            }
            .contractList .list-style {
                margin-top:.48rem;
            }
            .list-style .list-item{
                width:7.02rem;
                height:2.47rem;
                background: #FFFFFF;
                border-radius: .2rem;
                box-sizing: border-box;
                padding: .22rem .24rem;
                margin: .2rem 0.08rem;
                box-shadow: 0 0 3px 3px #F5FAFE;
            }
            .list-style .list-item .dots{
                display: block;
                width: .4rem;
                   height: .4rem;
                float:right;
                background:url(img/dots-horizontal-roun.png) no-repeat;
                background-size: 100%;
            }
            /*状态样式*/
            .list-style .list-item .contract-status{
                float: right;
                font-size: .26rem;
                line-height: .68rem;
                color:#FA8F35;
            }
            
            .list-style .list-item  .hasApplyed{
                color: #2D8DF1;
            }
            .contract-num,.contract-firm,.contract-dept{
                display:inline-block;
                width:.3rem;
                height:.3rem;
                margin-right:.1rem;
            }
            .contract-num{
                background: url(img/contractNum.png) no-repeat;
                background-size: 100%;
            }
            .contract-firm{
                background: url(img/confirm.png) no-repeat;
                background-size: 100%;
            }
            .contract-dept{
                background: url(img/contract-category.png) no-repeat;
                background-size: 100%;
            }
            .list-style .list-item  .contract-title{
                width: 80%;
                white-space: nowrap;
                overflow-x: hidden;
                text-overflow: ellipsis;
                font-size: .32rem;
                color:#000000;
                font-weight: 400;
                
            }
            .list-style .list-item .content{
                display:flex;
                margin:.2rem 0;
            }
            .list-style .list-item  .content-style{
                font-size: .24rem;
                color: #333333;
                width:68%;
                overflow: hidden;
                white-space: nowrap;
                text-overflow: ellipsis;
            }
            .list-style  .addMore{
                text-align: center;
                font-size: .24rem;
                line-height: 2;
                color: #111111;
            }
            .list-style .nodataImg{
                width: 64%;
                margin: 0 18%;
            }
            .authorzeList .list-style::before{
                content: "";
                display: block;
                clear: both;
            }
            .list-style .list-item .list-label{
                color: #8F8E94;
                font-size: .24rem;
            }
           
            .lawCon{
                width:7.18rem;
                height: 4rem;
                box-sizing: border-box;
                padding: .44rem .28rem .22rem .28rem;
                background: #FFFFFF;
                border-radius: 10px;
                box-shadow:0px 4px 4px 0px rgba(0, 0, 0, 0.1);
                margin-top:.2rem;
            }
            .lawCon .law-title{
                font-weight:600;
                font-size: .32rem;
                color: #252525;
            }

    这个的页面布局就是现在大家看到的这样。js去控制页面滑动时触发的事件

    首先rem对应px的js

    由于我们的设计图是750px的,所以是除以的750比例

document.documentElement.style.fontSize = document.documentElement.clientWidth / 750 * 100 + 'px';

    接下来说一下在页面滑动时的js事件

    首先要根据屏幕大小确定页面可滚动区域的高度,然后设置主体部分距离顶部的top值就好

    

       window.onload = function(){
                var totalHeight = window.screen.height;
                var topDistance = $('.mainBox').position().top;
                var navListHeight = $('.navList').height();
                $('#main').css({'height':(totalHeight-topDistance-navListHeight)+'px','overflow':'auto'})
            }
            var mainPart = document.getElementById('main');
            var startX, startY, moveEndX, moveEndY,  Y;  
            mainPart.addEventListener('touchstart',function(e){
                startX = e.touches[0].pageX;
                
                startY = e.touches[0].pageY
            })
            mainPart.addEventListener('touchmove',function(e){
                var topDistance = $('.mainBox').position().top;
                var distance = $('html').css('font-size').split('px')[0];
                distance = Number(distance) * 3.53;
                
                var topVal = $(this).scrollTop();
                
                moveEndX = e.changedTouches[0].pageX;
                
                moveEndY = e.changedTouches[0].pageY;
         
                  X = moveEndX - startX;
                  
                Y = moveEndY - startY;
         
                  if ( Y > 0 && Math.abs(Y)>Math.abs(X)) {
                    if ( topVal<=30) {
                        $('.mainBox').css('top',distance+'px')
                    }
                
               }else if ( Y < 0  && Math.abs(Y)>Math.abs(X) ) {
                    var result = topDistance-topVal>60?(topDistance-topVal):60;
                    $('.mainBox').css('top',result+'px')
                
                }

            })

 

  

posted @ 2019-05-12 20:34  前端加油站  阅读(994)  评论(0编辑  收藏  举报