这个问题的关键在于,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表示元素左上角到页面上边和左边的距离。如图所示
用这个方法实现上面所说的在表格的可视区域内居中那就很简单了。
大家可以试着自己实现一下。
下面我贴出我的代码。
<html lang="en"><head> <meta charset="UTF-8"> <title>Documenttitle> <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。
以上的这些情况,有兴趣的可以自己完整的实现一下。或者有不同做法的,欢迎评论区留言,一起讨论。