pc端网页缩放的方案探索
最近领导给了个需求:一个web页面header和footer的部分不能随浏览器zoom in/out 改变样式及字体大小。
分析了需求和查阅相关资料后,写个demo,实现了整个页面不随ctrl+(+/-) 组合键或者ctrl+鼠标滚轮 缩放的效果,对于浏览器工具/设置的缩放没有效果。
键盘/鼠标事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- 缩放比例仅在移动端有效,在pc端无效 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=3,minimum-scale=0.5" />
<title>Document</title>
</head>
<body></body>
</html>
<html>
<head> </head>
<body style="font-size: 30px">
<div class="header"><h1>测试</h1></div>
<div class="content"><br />SCRIPT脚本控制页面不随ctrl+鼠标滚轮而缩放。<br /></div>
</body>
<script>
let gloable_key = { ctrlDown: false };
//禁止Ctrl + (+/-)组合
//event.ctrlKey:键盘的Ctrl键 event.metaKey:mac上的Command
document.addEventListener(
"keydown",
function (event) {
if (event.ctrlKey === true || event.metaKey === true) {
gloable_key["ctrlDown"] = true; //如果ctrl键按下,记录到变量
}
if ((event.ctrlKey === true || event.metaKey === true) && (event.which === 61 || event.which === 107 || event.which === 173 || event.which === 109 || event.which === 187 || event.which === 189)) {
event.preventDefault(); //阻止默认缩放
}
},
false
);
// 禁止Ctrl + 鼠标轮滑
//DOMMouseScroll是火狐对鼠标轮滑的监听事件。mousewheel是Chrome,IE对鼠标轮滑的监听事件
document.addEventListener(
"DOMMouseScroll",
function (event) {
if ("ctrlDown" in gloable_key && gloable_key["ctrlDown"]) {
event.preventDefault(); //阻止默认缩放
}
},
{ passive: false }
);
document.addEventListener(
"mousewheel",
function (event) {
if ("ctrlDown" in gloable_key && gloable_key["ctrlDown"]) {
event.preventDefault(); //阻止默认缩放
}
},
{ passive: false }
);
</script>
</html>
然而单个元素添加以上效果,该怎么做呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- 缩放比例仅在移动端有效,在pc端无效 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=3,minimum-scale=0.5" />
<title>Document</title>
</head>
<body></body>
</html>
<html>
<head> </head>
<body style="font-size: 30px">
<div class="header">
<h1>测试</h1>
</div>
<div class="content"><br />SCRIPT脚本控制页面不随ctrl+鼠标滚轮而缩放。<br /></div>
</body>
<script>
let gloable_key = { ctrlDown: false };
let elem_header = document.querySelector(".header");
//禁止Ctrl + (+/-)组合
//event.ctrlKey:键盘的Ctrl键 event.metaKey:mac上的Command
document.addEventListener(
"keydown",
function (event) {
if (event.ctrlKey === true || event.metaKey === true) {
gloable_key["ctrlDown"] = true; //如果ctrl键按下,记录到变量
}
if ((event.ctrlKey === true || event.metaKey === true) && (event.which === 61 || event.which === 107 || event.which === 173 || event.which === 109 || event.which === 187 || event.which === 189)) {
event.preventDefault(); //阻止默认缩放
}
},
false
);
// 禁止Ctrl + 鼠标轮滑
//DOMMouseScroll是火狐对鼠标轮滑的监听事件。mousewheel是Chrome,IE对鼠标轮滑的监听事件
elem_header.addEventListener(
"DOMMouseScroll",
function (event) {
if ("ctrlDown" in gloable_key && gloable_key["ctrlDown"]) {
event.preventDefault(); //阻止默认缩放
}
},
{ passive: false }
);
elem_header.addEventListener(
"mousewheel",
function (event) {
if ("ctrlDown" in gloable_key && gloable_key["ctrlDown"]) {
event.preventDefault(); //阻止默认缩放
}
},
{ passive: false }
);
</script>
</html>
效果就是鼠标放到header区域,不随ctrl+(+/-) 组合键或者ctrl+鼠标滚轮 缩放,鼠标放到content区域,随意缩放,显然不是想要的效果。
依靠键盘事件似乎达不到控制区域的精细效果,header上绑定的键盘事件也不会在header上按下键盘按键触发键盘事件的效果。没思路了。


css的zoom和transform-scale
<html>
<head> </head>
<body>
<div class="header" style="border: 1px silver solid; padding: 0.25rem; height: 300px; overflow-y: auto">
<div class="content_scale" style="background-color: aqua">
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
</div>
</div>
<div class="header" style="border: 1px silver solid; padding: 0.25rem; height: 300px; overflow-y: auto">
<div class="content_zoom" style="background-color: bisque">
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
<h1>测试</h1>
</div>
</div>
<div style="border: 1px silver solid; padding: 0.25rem">
<h1>对比</h1>
</div>
</body>
<script>
let gloabl_scale = 1.0;
let elem_scale = document.querySelector(".content_scale");
elem_scale.addEventListener("mousewheel", handleScale, { passive: false });
elem_scale.addEventListener("DOMMouseScroll", handleScale, { passive: false });
function handleScale(event) {
//event.deltaY > 0 滚轮朝前滑动
if (event.deltaY > 0) {
gloabl_scale += 0.1;
if (gloabl_scale > 2.0) gloabl_scale = 2.0;
elem_scale.style.transform = "scale(" + gloabl_scale + ")";
elem_scale.style.transformOrigin = "0 0";
} else {
gloabl_scale -= 0.1;
if (gloabl_scale < 0.5) gloabl_scale = 0.5;
elem_scale.style.transform = "scale(" + gloabl_scale + ")";
elem_scale.style.transformOrigin = "0 0";
}
}
let gloabl_zoom = 1.0;
let elem_zoom = document.querySelector(".content_zoom");
elem_zoom.addEventListener("mousewheel", handleZoom, { passive: false });
elem_zoom.addEventListener("DOMMouseScroll", handleZoom, { passive: false });
function handleZoom(event) {
//event.deltaY > 0 滚轮朝前滑动 放大
if (event.deltaY > 0) {
gloabl_zoom += 0.1;
if (gloabl_zoom > 2.0) gloabl_zoom = 2.0;
} else {
gloabl_zoom -= 0.1;
if (gloabl_zoom < 0.5) gloabl_zoom = 0.5;
}
elem_zoom.style.zoom = gloabl_zoom;
}
</script>
</html>
以下三图分别是无缩放、最小、最大的结果



使用zoom缩放较符合需求,缩放区域缩小后无滚动条,而scale的滚动条始终都在。然而firefox浏览器到今天仍然不支持zoom,只得放弃此种方案。
css字体单位
试下缩放对不同的字体单位的影响
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
width: 100vw;
}
div {
border: 1px solid red;
}
p {
border: 1px solid silver;
}
.vh {
font-size: 2vh;
}
.vw {
font-size: 1vw;
}
.px {
font-size: 20px;
}
.em {
font-size: 2em;
}
.rem {
font-size: 2rem;
}
</style>
</head>
<body>
<div class="vh">
vh单位:2vh
<p style="font-size: 4vh">vh单位:4vh</p>
<p style="font-size: 6vh">vh单位:6vh</p>
<p style="font-size: 8vh">vh单位:8vh</p>
</div>
<div class="vw">
vw单位:1vw
<p style="font-size: 2vw">vw单位:2vw</p>
<p style="font-size: 4vw">vw单位:4vw</p>
</div>
<div class="px">px单位:20px</div>
<div class="em">em单位:2em</div>
<div class="rem">
rem单位:2rem
<p style="font-size: 4rem">rem单位:4rem</p>
</div>
</body>
</html>
vh和vw单位在25%-100%缩放比例时字体大小保持基本不变,100%-500%缩放比例字体增大;<
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.main-header {
font-size: 2vh;
height: 10vh;
line-height: 10vh;
border: 1px solid red;
}
.content {
font-size: 1.2rem;
border: 1px solid red;
height: 85vh;
line-height: 85vh;
}
html {
overflow: hidden;
}
iframe {
display: block;
border: none;
height: 85vh;
width: 100%;
}
</style>
</head>
<body>
<div class="main-header">LOGO</div>
<div class="content">
<iframe src="./test/table.html" height="85vh" width="100%"></iframe>
</div>
</body>
</html>
效果如此,没思路了
浙公网安备 33010602011771号