最近公司要做一个数据可视化页面,要求大小屏兼容。网上查找了一些资料后,得出了一个代码量少、实现简单的自适应方案。下面放出全部代码,可以复制自行查看效果和代码优化。
HTML:
<div>
<div class="wrapper">
<div class="container">
<div class="box1">
<div class="box1-left">左</div>
<div class="box1-main">中</div>
<div class="box1-right">右</div>
</div>
<div class="box2">
<div class="box2-item">1</div>
<div class="box2-item">2</div>
</div>
</div>
</div>
</div>
CSS:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
}
.wrapper {
position: relative;
}
.container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: 20px;
transform-origin: 0 0;
}
.box1 {
display: flex;
gap: 20px;
height: 640px;
}
.box2 {
flex: 1;
}
.box1 .box1-left {
width: 410px;
background-color: rosybrown;
}
.box1 .box1-main {
flex: 1;
background-color: antiquewhite;
}
.box1 .box1-right {
width: 410px;
background-color: darkseagreen;
}
/* box2 */
.box2 {
display: flex;
gap: 20px;
}
.box2 .box2-item {
width: 50%;
}
.box2-item:nth-child(1) {
background-color: bisque;
}
.box2-item:nth-child(2) {
background-color: cadetblue;
}
JS
// 获取容器
const wrapper = document.querySelector('.wrapper');
const container = document.querySelector('.container');
function debounce(fn, delay) {
let timer = null;
return function() {
let _this = this;
let args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(_this, args)
}, delay);
}
}
function reset() {
// 获取body宽高
const bWidth = document.body.clientWidth;
const bHeight = document.body.clientHeight;
// 获取宽高比例
const width = bWidth / 1920;
const height = bHeight / 929;
// 设置缩放
let scale = width > height ? height : width;
console.log('缩放倍数', scale);
// 给容器添加样式,基于1920px * 929px缩放scale倍
container.style = `width: 1920px; height: 929px; transform: scale(${scale}, ${scale})`;
// ---------居中逻辑---------
// 计算出容器实际大小
let cWidth = container.clientWidth * scale;
let cHeight = container.clientHeight * scale;
console.log('container', cWidth, cHeight);
// 设置外层容器(解决缩放前大小引起的滚动条)
wrapper.style = `width: ${cWidth}px; height: ${cHeight}px; overflow: hidden;`;
// 计算出空白空间
let margin = (bWidth - cWidth) / 2;
console.log('margin', margin);
if (bHeight < 1080) {
wrapper.parentNode.style = `margin: 0 ${margin}px;`;
}
}
reset();
window.addEventListener('resize', debounce(reset, 300));
此方案参考了网上某些案例,实现了大小屏自适应;参考了百度某XX数据大屏实例代码,解决了自适应过程中的居中问题和其他一些小缺陷;优点:在几乎所有屏幕中(<=1920px)自适应效果奇佳;缺点:因为没有更大尺寸设备来做实验,所以1920*1080之上的尺寸自适应需要自行调节代码内的一些配置