CSS实现页面切换时的滑动效果

时间:2024-01-28 15:56:57

最近在开发手机端APP页面功能时遇到一个需求:某个页面查询的数据有三种分类,需要展示在同一页面上,用户通过点击分类标签来查看不同类型的数据, 期望效果是
用户点击标签切换时另一个页面能够以一个平滑切入的方式展示数据.
示意图如下:

话不多说了.

首先上CSS

<style type="text/css">
 html, body{
    height: 100%; 
 }
 body{
	overflow:hidden; /*设置超出页面部分隐藏*/
	margin: 0;/*初始化页面默认边距*/
        padding: 0;
        font-family: sans-serif;
 }
.page-title-text {
    padding-left: 17%;
}

 .layui-select-condition {
 	position:fixed;
 	padding-top: 16px;
 	width:100%;
        display: none;
        z-index:999;
        background-color: white;
 }
 
.layui-form-select .layui-input {
    padding-right: 30px;
    cursor: pointer;
    border: 0px;
}
.layui-bottom button{
    border: none;
    line-height: 50px;
    height: 50px;
    width: 100%;
}

.line-block-container{
	display: inline;
    width: 100%;
    line-height: 20px;
    margin-left: 3%;
    padding: 0;
}
.layui-tab-title li a{
    display: inline-block;
    background: rgb(255 255 255);
    color: #5d5d5d;
    border: 1px solid #5d5d5d;
    width: 26%;
    height: 20px;
    line-height: 20px;
    text-align: center;
    font-size: 12px;
    position: absolute;
    top: 22%;
}
.layui-tab-title li a {
    display: inline-block;
}
.zui-col-fitable{
	margin-left: 5%;
    margin-right: 6%;
    padding: 0;
    position:relative;
}
.zui-line-separater{
    height: 2px;
    margin-left: 3%;
}
hr{
	margin:3px 0;
}
.zui-col-fitable input{
		border:0;
		outline:none;
    }
#alarmTime:focus{
        border:1px solid #66ccff!important;
    }
 /*给三个子页面的容器添加CSS,设置布局为相对布局的原因是为了实现页面切换效果*/   
.zui-slide-container{
	position:relative;
	margin-top: 50px; 
	height:100%;
	width:100%;
	overflow:hidden;
	text-align: center;
}
/*给子页面的div设置为绝对定位与父容器的相对定位结合使用实现div布局*/
.zui-slide-container>div{
	position: absolute;
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        -webkit-transition: all 0.25s ease-in-out; /*为页面设置显示时的切换效果与切换速度,可以在浏览器中调整切换速度来找到自己合适的速度*/
        transition: all 0.25s ease-in-out;
        top: 0;	
}
/*
  设置各个页面的初始位置,后面会有用到
*/
#alarmLevel1{
	left:-100%
}
#alarmLevel2{
	left:-100%
}
#alarmLevel3{
	left:-100%
}
/*
    设置当各个子DIV添加move的CSS时,div的位置  
*/
#alarmLevel1.move{
    left: 0;
}
#alarmLevel2.move{
    left: 0;
}
#alarmLevel3.move{
    left: 0;
}


.div-align-right{
	left:100%
}
.div-align-left{
	left:-100%
}
#tpl span{
    margin: 0;
    padding: 0;
    float: left;
}
.zui-this{
}
</style>

上页面布局:

<div class="div-main">
		<div class="page-title">
			<div class="layui-row" style="color:#ffffff">
				<div class="layui-col-xs4">
		      		<div class="back-area">
						<i class = "layui-icon layui-icon-left" onclick="getBack()"></i>
					</div>
		      	</div>
				<div class="layui-col-xs4">
		      			<div class="page-title-text">	
							预警层级
						</div>
		      	</div>
				<div class="layui-col-xs4">
		      	</div>
		    </div>
		</div>
		<div class="div-main-body">
			<div class="layui-tab layui-row layui-tab-brief" lay-filter="dataContainer" style="margin: 0px;">
				<ul class="layui-tab-title">
					<li style="display:inline;padding:0px;">
						<div style="position:relative;height:40px;">
							<a href="#alarmLevel1" data-level = "1" data-brother="alarmLevel2,alarmLevel3" style="border-radius:5px 0px 0px 5px;left: 11%;">层级一</a>
							<a href="#alarmLevel2" data-level = "2" data-brother="alarmLevel1,alarmLevel3" style="border-radius: unset;left:37%">层级二</a>
							<a href="#alarmLevel3" data-level = "3" data-brother="alarmLevel2,alarmLevel1" style="border-radius:0px 5px 5px 0px;left:63%">层级三</a>
						</div>
					</li>
				</ul>
			</div>
			<div class="zui-slide-container">
			  		<div id="alarmLevel1" style="width:100%;height:100%;position:absolute;">
			  			<table id="alarmLevelGrid1" lay-filter="alarmLevel1" class="layui-hide"></table>
			  		</div>
			  		<div id="alarmLevel2" style="width:100%;height:100%;position:absolute;" >
			  			<table id="alarmLevelGrid2" lay-filter="alarmLevel2" class="layui-hide"></table>
			  		</div>
			  		<div id="alarmLevel3" style="width:100%;height:100%;position:absolute;">
			  			<table id="alarmLevelGrid3" lay-filter="alarmLevel3" class="layui-hide"></table>
			  		</div>
			 </div>
		</div>
</div>		

布局没什么好说的,主要就是根据原型图来设置各个div的位置.

javascript代码

<script type="text/javascript">
	"use strict"
	var table = layui.table;
	var $ = layui.jquery;
	
	loadTableData();
	
	function loadTableData(){
		var alarmLevel = $("zui-this").attr("data-level");
		loadData({"alarmLevel":alarmLevel});
	}
	
	function loadData(searchParams){
			  table.render({
			    elem: '#alarmLevelGrid1'
			    ,id:'alarmLevelGrid1'
			    ,url:'xxxx/xxx/getData'
			    ,toolbar: false
			    ,title: '预警层级记录表'
			    ,totalRow: false
			    ,limits:[3,5,10,20]
			    ,limit:5
			    ,cols: [[
			      {
					  field:'alarmLevel',  // 只需要在此处选择一个必定存在的元素作为渲染条件即可
					  title:'预警层级', 
					  width:400, 
					  templet:'#alarmLevelTpl'
				}
			    ]]
			    ,page: true
			    ,where :{"alarmLevel":"1"}
			    ,response: {
			      statusCode: 200 //重新规定成功的状态码为 200,table 组件默认为 0
			    }
			    ,parseData: function(res){ 
			     return {
			        "code": res.code==0?200:404, //解析接口状态
			        "msg": res.msg, //解析提示文本
			        "count": res.total, //解析数据长度
			        "data": res.level //解析数据列表
			      };
			    }
				,done: function (res, curr, count){
                                              // done函数的妙用,利用表格数据完成后,调整对应的css可以将layui的pc端表格设置成兼容手机端模式
						$("div[lay-id=alarmLevelGrid1]").css("margin-top", "11%");
						layui.$('.layui-table-view .layui-table').css("width","100%");
						layui.$('table tbody tr td div').attr("class","");
						layui.$('table tbody tr td').css("display","inline-flex");
						layui.$('table tbody tr td').css("border-width","1px");
						layui.$('table tbody tr td').css("border-color","#66CCFF");
						layui.$('table tbody tr td').css("border-radius","1rem");
						layui.$('table tbody tr td').css("border-style","solid");
						layui.$('table tbody tr td').css("margin-left","3%");
						layui.$('table tbody tr td').css("width","94%");
						layui.$('table tbody tr td').css("padding-left","12px");
						layui.$('table tbody tr td').removeAttr("data-content");
						layui.$('table tbody tr td').removeAttr("data-edit");
						// 隐藏手机端不需要的部分
						layui.$('.layui-table-header').css("display","none");
						layui.$('.layui-table-tool').css("display","none");  
						layui.$('.layui-table-total').css("display","none");
						
						// 处理分页条内容
						layui.$('.layui-table-page').css("width","100%");
						
						$('.layui-laypage-skip').remove();
						layui.$('table').css("border-collapse","separate");
						layui.$('table').css("border-spacing","0px 10px");
					
					}
			  });
			  
			   table.render({
			    elem: '#alarmLevelGrid2'
			    ,id:'alarmLevelGrid2'
			    ,url:'xxxx/assf/xx/getData'
			    ,toolbar: false
			    ,title: '预警层级记录表'
			    ,totalRow: false
			    ,limits:[3,5,10,20]
			    ,limit:5
			    ,cols: [[
			      {
					  field:'alarmLevel',  // 只需要在此处选择一个必定存在的元素作为渲染条件即可
					  title:'预警层级', 
					  width:400, 
					  event: 'viewDetail',
					  templet:'#alarmLevelTpl'
				}
			    ]]
			    ,page: true
			    ,where :{"alarmLevel":"2"}
			    ,response: {
			      statusCode: 200 //重新规定成功的状态码为 200,table 组件默认为 0
			    }
			    ,parseData: function(res){ 
			     return {
			        "code": res.code==0?200:404, //解析接口状态
			        "msg": res.msg, //解析提示文本
			        "count": res.total, //解析数据长度
			        "data": res.level //解析数据列表
			      };
			    }
				,done: function (res, curr, count){
						$("div[lay-id=alarmLevelGrid2]").css("margin-top", "11%");
						layui.$('.layui-table-view .layui-table').css("width","100%");
						layui.$('table tbody tr td div').attr("class","");
						layui.$('table tbody tr td').css("display","inline-flex");
						layui.$('table tbody tr td').css("border-width","1px");
						layui.$('table tbody tr td').css("border-color","#66CCFF");
						layui.$('table tbody tr td').css("border-radius","1rem");
						layui.$('table tbody tr td').css("border-style","solid");
						layui.$('table tbody tr td').css("margin-left","3%");
						layui.$('table tbody tr td').css("width","94%");
						layui.$('table tbody tr td').css("padding-left","12px");
						layui.$('table tbody tr td').removeAttr("data-content");
						layui.$('table tbody tr td').removeAttr("data-edit");
						// 隐藏手机端不需要的部分
						layui.$('.layui-table-header').css("display","none");
						layui.$('.layui-table-tool').css("display","none");  
						layui.$('.layui-table-total').css("display","none");
						
						// 处理分页条内容
						layui.$('.layui-table-page').css("width","100%");
						
						$('.layui-laypage-skip').remove();
						layui.$('table').css("border-collapse","separate");
						layui.$('table').css("border-spacing","0px 10px");
					
					}
			  });
			table.render({
			    elem: '#alarmLevelGrid3'
			    ,id:'alarmLevelGrid3'
			    ,url:'xxxx/sxxx/getData'
			    ,toolbar: false
			    ,title: '预警层级记录表'
			    ,totalRow: false
			    ,limits:[3,5,10,20]
			    ,limit:5
			    ,cols: [[
			      {
					  field:'alarmLevel',  // 只需要在此处选择一个必定存在的元素作为渲染条件即可
					  title:'预警层级', 
					  width:400, 
					  event: 'viewDetail',
					  templet:'#alarmLevelTpl'
				}
			    ]]
			    ,page: true
			    ,where :{"alarmLevel":"3"}
			    ,response: {
			      statusCode: 200 //重新规定成功的状态码为 200,table 组件默认为 0
			    }
			    ,parseData: function(res){ 
			     return {
			        "code": res.code==0?200:404, //解析接口状态
			        "msg": res.msg, //解析提示文本
			        "count": res.total, //解析数据长度
			        "data": res.level //解析数据列表
			      };
			    }
				,done: function (res, curr, count){
						$("div[lay-id=alarmLevelGrid3]").css("margin-top", "11%");
						layui.$('.layui-table-view .layui-table').css("width","100%");
						layui.$('table tbody tr td div').attr("class","");
						layui.$('table tbody tr td').css("display","inline-flex");
						layui.$('table tbody tr td').css("border-width","1px");
						layui.$('table tbody tr td').css("border-color","#66CCFF");
						layui.$('table tbody tr td').css("border-radius","1rem");
						layui.$('table tbody tr td').css("border-style","solid");
						layui.$('table tbody tr td').css("margin-left","3%");
						layui.$('table tbody tr td').css("width","94%");
						layui.$('table tbody tr td').css("padding-left","12px");
						layui.$('table tbody tr td').removeAttr("data-content");
						layui.$('table tbody tr td').removeAttr("data-edit");
						// 隐藏手机端不需要的部分
						layui.$('.layui-table-header').css("display","none");
						layui.$('.layui-table-tool').css("display","none");  
						layui.$('.layui-table-total').css("display","none");
						
						// 处理分页条内容
						layui.$('.layui-table-page').css("width","100%");
						
						$('.layui-laypage-skip').remove();
						layui.$('table').css("border-collapse","separate");
						layui.$('table').css("border-spacing","0px 10px");
					
					}
			  });
	  }

	function selectDefault(){
		$("a[data-level = 1]").click();
	}
	// 为导航栏目添加绑定事件
        /*
          该段js代码的核心就是当点击类型标签时,为对应的div 添加move 样式(上述css中有写),
          同时移除其他两个div的move样式,这样就可以实现页面滑动切换的效果啦.这样的动态效果还有很
          多例如:旋转,栅格等等,感兴趣的读者朋友可以自行试验
        */
	$('a[data-level=1]').click(function(e){
	  if($(this).hasClass("zui-this"))
		return;
	  reloadTable("alarmLevelGrid1",{"alarmLevel":"1"});
	  resetSelectedStyle();
          $(".zui-this").removeClass("zui-this");
          $(this).addClass("zui-this");
	  renderSelectedStyle(this);
           e.preventDefault();
    	 $('#alarmLevel2').removeClass("move");
    	 $('#alarmLevel1').removeClass("div-align-left");
    	 $('#alarmLevel2').removeClass("div-align-right");
    	 $('#alarmLevel3').removeClass("div-align-right");
    	 $('#alarmLevel3').removeClass("move");
    	 $('#alarmLevel1').toggleClass('move');
     });	
	
	$('a[data-level=2]').click(function(e){
		
		if($(this).hasClass("zui-this"))
			return;
		reloadTable("alarmLevelGrid2",{"alarmLevel":"2"});
		resetSelectedStyle();
        $(".zui-this").removeClass("zui-this");
        $(this).addClass("zui-this");
		renderSelectedStyle(this);
         e.preventDefault();
         $('#alarmLevel2').toggleClass('move');
         $('#alarmLevel2').removeClass("div-align-right");
         $('#alarmLevel2').removeClass("div-align-left");
    	 
         $('#alarmLevel1').removeClass("move");
    	 $('#alarmLevel3').removeClass("move");
     });		

	$('a[data-level=3]').click(function(e){
		if($(this).hasClass("zui-this"))
			return;
		reloadTable("alarmLevelGrid3",{"alarmLevel":"3"});	
	 	resetSelectedStyle();
        $(".zui-this").removeClass("zui-this");
        $(this).addClass("zui-this");
		renderSelectedStyle(this);
         e.preventDefault();
         $('#alarmLevel1').removeClass("move");
    	 $('#alarmLevel2').removeClass("move");
    	 $('#alarmLevel1').toggleClass("div-align-right");
    	 $('#alarmLevel2').toggleClass("div-align-right");
    	 $('#alarmLevel1').removeClass("div-align-left");
         $('#alarmLevel3').toggleClass('move');
     });
     
    // 由于css的就近原则,使用class 无法达到预期效果,使用jquery增加样式
    function resetSelectedStyle(){
    	$(".zui-this").css("color","#333");
	 	$(".zui-this").css("background-color","white");
    } 
     
    function renderSelectedStyle(elem){
        $(elem).css("color","white");
        $(elem).css("background-color","#1e9fff");
    }  
     
	// 表格重载
	function reloadTable(gridLayId,params){
		let baseParam = {"isMobile":true};
		$.extend(true,baseParam,params);
		table.reload(gridLayId,{
			   page: {
	                    curr: 1 
	                },
			 	where : baseParam			 		
			});	
	}
	// 返回	
	function getBack(){
		clearContext();
		history.back(-1);
	}
	
	// 清理空间
	function clearContext(){
		c.remove("searchParams");
	} 
	
	function getUserName(d){
		if(d.writeUser){
			return d.writeUser.empName;
		}
		return "";
	}
	$(document).ready(function(){
		 selectDefault();
	});
</script>