这个问题的关键在于,loading在可见区域内居中。如果只是让loading元素在表格内居中,那很容易,css就可以实现。但是可见区域内居中的话,loading就要fixed布局,这样loading的top值是动态变化的,下面看几张图片,就会一目了然了。
loading在表格内居中。
这是在表格内居中的loading,显而易见,当表格过长时,点击查询只能看到遮罩,而看不到loading。所以需要优化,优化的效果是在可视区内看到loading。
loading在表格的可见区域内居中。当滚动的时候,也要保证loading实时居中。
图一
**图二**
图三
从这三张图可以看出,loading的位置不是一直不变的,而是一直在表格的可视区域内居中的,
怎么实现这种效果呢?
这里用到javascript中的 getBoundingClientRect() 方法。
Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。
<div class="table-wrap" id="table">
表格内容
</div>
<script>
window.onload = function() {
let tableEle = document.getElementById("table");
let tableClientRect = tableEle.getBoundingClientRect();
console.log(tableClientRect);
}
</script>
// getBoundingClientRect()返回一个DOMRect对象。值如下:
// DOMRect {x: 30, y: 160, width: 351.8374938964844, height: 2000, top: 160,bottom: 2160, left: 30,right: 381.8374938964844}
**getBoundingClientRect() ** 返回值有八个属性:left、top、right、bottom、x、y、width、height。
left、top、right和bottom。分别表示元素各边与页面上边和左边的距离。x、y表示元素左上角到页面上边和左边的距离。如图所示
用这个方法实现上面所说的在表格的可视区域内居中那就很简单了。
大家可以试着自己实现一下。
下面我贴出我的代码。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.content-wrap{
width: 100%;
overflow-y: auto;
}
.search-wrap{
width: 30%;
height: 100px;
background: #417bff;
color: #fff;
text-align: center;
margin: 30px;
}
.table-wrap{
width: 30%;
height: 2000px;
background: #985ee4;
color: #fff;
text-align: center;
margin: 30px;
position: relative;
}
.loading-mark{
width: 100%;
height: 100%;
background: rgba(0,0,0,0.2);
position: absolute;
left:0;
top: 0;
}
/*相对于表格居中,当表格过长,loading可能看不见*/
/*.loading-text{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}*/
.loading-text{
position: fixed;
transform: translate(-50%,-50%);
}
.footer-wrap{
width: 30%;
height: 200px;
text-align: center;
background: #314B8C;
color: #fff;
margin: 30px;
}
</style>
</head>
<body>
<div class="content-wrap" id="main">
<div class="search-wrap">查询区域</div>
<div class="table-wrap" id="table">
表格内容
<div class="loading-mark"></div>
<div class="loading-text" id="loading">loading...</div>
</div>
<div class="footer-wrap">
底部内容
</div>
</div>
<script>
window.onload = function() {
let tableEle = document.getElementById("table");
let loadingEle = document.getElementById("loading");
let tableClientRect = tableEle.getBoundingClientRect();
let winH = document.documentElement.clientHeight;
document.getElementById("main").style.height = winH +'px';
//console.log(tableClientRect);
/*
* 用fiexd 布局,loading在表格可视范围内居中,left和top都需要计算。
* 初始进来页面时,也就是图一的状态
* */
loadingEle.style.top = (winH-tableClientRect.top)/2 + tableClientRect.top + 'px';
loadingEle.style.left = tableClientRect.width/2 + tableClientRect.left + 'px';
/*
* 滚动页面时
* */
document.getElementById("main").addEventListener('scroll',function() {
tableClientRect = tableEle.getBoundingClientRect();
// 滚动的时候,图一状态的loading的top值
if (tableClientRect.top>0 && tableClientRect.bottom>winH) {
loadingEle.style.top = (winH-tableClientRect.top)/2 + tableClientRect.top + 'px';
}
// 滚动的时候,图二状态的loading的top值
if (tableClientRect.top<0 && tableClientRect.bottom>winH) {
loadingEle.style.top = winH/2;
}
// 滚动的时候,图三状态的loading的top值
if (tableClientRect.top<0 && tableClientRect.bottom<winH) {
loadingEle.style.top =tableClientRect.bottom/2 + 'px';
}
});
}
</script>
</body>
</html>
以上,只是一种情况,实际的项目场景中,刚进来的时候,表格还没有请求数据的时候,表格肯定是没有那么长的。那计算的方式也就不是上面图一的计算方式了。
下面看图片,这样也很容易的知道,loading的top 应该是
top = (tableClientRect.bottom - tableClientRect.top)/2 + tableClientRect.top;
还有可能的情况是:进来页面的时候,表格没在可视区,这种情况也是要做处理的,否则可能在点击查询的时候没有看到表格却看到了loading。
以上的这些情况,有兴趣的可以自己完整的实现一下。或者有不同做法的,欢迎评论区留言,一起讨论。