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>
效果如此,没思路了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix