首页 > 应用开发 > Html/css > Web移动端 自适应缩放界面
在开发App端的网页时,要适配iphone、ipad、ipod、安卓等各种机型,一般是直接使用em、px转em、界面缩放。
本章是通过将界面缩放,等比例显示在各机型上。过程中遇到了些问题和大坑~
首先设置内容固定宽度、自动高度(以下举例)
添加一段设置zoom值的函数:
1 getScript() {2 return `3 const zoomValue=window.innerWidth / 375;4 document.documentElement.style.transform="scale("+zoomValue+")";5 document.documentElement.style.transformOrigin="left top";6 `;7 }注:
以上也可以直接写script,我上面返回一段html是因为项目是通过 服务端渲染的。
样式的设置必须在界面加载之前,否则会因界面显示变更出现闪现问题。
因为添加了服务端渲染,所以无法在界面一开始初始时,无法获取window、document等对象。而上面html的注入,对服务端渲染机制的一个黑科技~
上面的方案完成后,看看效果。然后坑出来了:
网上找到了一篇文章 CSS3 transform对普通元素的N多渲染影响 ,介绍了transform的一堆坑。
我这个项目一些布局需要position=fixed,所以tranform不适合~放弃
这个坑的其它介绍可以参考下:
总结:
在上一个方案的基础上,尝试zoom缩放:
1 getScript() {2 return `3 const zoomValue=window.innerWidth / 375;4 document.documentElement.style.zoom = zoomValue;5 `;6 }emmm,很简单,调试效果看起来很不错。模拟机上,看起来都正常~
但是坑来了: 真机有问题,发现在ipad的safari上,页面是放大了,但是字段根本就没变化!
原因竟然是:苹果在ipad的网页,改动渲染方面的相关规则。有点坑~
https://apple.stackexchange.com/questions/377216/css-zoom-does-not-work-ipad-os-v13-latest-safari
https://stackoverflow.com/questions/7907760/why-the-font-size-wont-change-with-browser-zoom-in
实现没办法,我后面尝试, 通过userAgent对ipad机型(ipad、macintosh)特殊处理,直接获取所有包含了文字的div、p、span等元素,放大font-size。
发现可以处理,没毛病!但是也有些缺陷,没办法在一开始处理字体,因为元素还没有初始化,而等界面加载后再刷字体大小,界面会闪现一次。
在html中添加默认viewport:
1 <meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1,user-scalable=no, minimal-ui"></meta>
ps:minimal-ui 与本文无关,它可以在safari加载网页时隐藏地址栏与导航栏
添加viewport更新:
1 getScript() {2 return `3 const zoomValue=window.innerWidth / 375;4 var viewport = document.querySelector("meta[name=viewport]");5 viewport.content="width=device-width,initial-scale="+zoomValue+", maximum-scale="+zoomValue+", minimum-scale="+zoomValue+",user-scalable=no, minimal-ui"6 `;7 }运行代码,emmm,有一些小问题。
fixed布局建议:以弹框为例
添加fixed布局的容器,水平竖直方向靠边距离分别设置一个就行了,left:0,bottom:0。
然后添加absolute布局的内容容器.如果需要居中,可以在js中设置bottom=window.innerHeight / 2 - 元素的高度/2
总结:
采用第二个zoom缩放方案,同时对ipad机型特殊处理,另外采用scale缩放方案。
完整代码如下:
1. 初始化适配(支持服务端渲染)
html-header添加script
1 {/* app contentAutoFit */}2 <script dangerouslySetInnerHTML={{ __html: this.getZoomScript() }}></script>自适应可执行代码文本
1 //返回自适应html字符串 2 getZoomScript() { 3 return ` 4 const zoomValue = window.innerWidth / 375; 5 const userAgentInfo = window.clientInformation.appVersion; 6 //如果是ipad 7 if (userAgentInfo.indexOf("iPad") != -1 || userAgentInfo.indexOf("Macintosh") != -1) { 8 //内容自适应 - 设置transform-scale。 9 //fixed布局时需要修改下left/margin-left等,同时窗口的宽高无法准确获取,需要除以比例,详见windowSizeWithScaleHelper10 //ipad有遗留问题:微信浏览器加载时,横竖屏切换一瞬间,有空白问题。不过可以忽略~11 document.documentElement.style.transform = "scale(" + zoomValue + "," + (zoomValue < 1 ? 1 : zoomValue) + ")";12 document.documentElement.style.transformOrigin = "left top";13 var html = document.querySelector("html");14 html.style.width = '375px';15 html.style.overflow = 'hidden';16 html.style.overflowY = 'auto';17 } else {18 //内容自适应 - 设置zoom。通过zoom来缩放界面,在ipad的safari浏览器等会存在字体无法缩放的兼容问题。19 document.documentElement.style.zoom = zoomValue;20 }21 // 内容自适应 - 设置viewport,整体okay。但是ipad的水平滚动条无法解决22 // var viewport = document.querySelector("meta[name=viewport]");23 // viewport.content = "width=device-width,initial-scale=" + zoomValue + ", maximum-scale=" + zoomValue + ", minimum-scale=" + zoomValue + ",user-scalable=no, minimal-ui"24 `;25 }2. 添加加载及界面变更刷新机制
1 componentDidMount() { 2 //window.onresize = this.adjustContentAutoFit; 3 //解决微信横竖屏问题 4 window.addEventListener("orientationchange", this.adjustContentAutoFit); 5 //解决加载过程中,切换横竖屏,导致界面没有适配的问题 6 this.adjustContentAutoFit(); 7 } 8 componentWillUnmount() { 9 window.removeEventListener("orientationchange", this.adjustContentAutoFit);10 }11 //监听窗口尺寸变更,刷新自适应12 adjustContentAutoFit() {13 const zoomValue = window.innerWidth / 375;14 const userAgentInfo = window.clientInformation.appVersion;15 //如果是ipad16 if (userAgentInfo.indexOf("iPad") != -1 || userAgentInfo.indexOf("Macintosh") != -1) {17 //内容自适应 - 设置transform-scale。18 //fixed布局时需要修改下left/margin-left等,同时窗口的宽高无法准确获取,需要除以比例,详见windowSizeWithScaleHelper19 //ipad有遗留问题:微信浏览器,横竖屏切换时,有些机型在打开一瞬间,有空白问题。不过可以忽略~20 document.documentElement.style.transform = "scale(" + zoomValue + "," + (zoomValue < 1 ? 1 : zoomValue) + ")";21 document.documentElement.style.transformOrigin = "left top";22 var html = document.querySelector("html") as HTMLElement;23 html.style.width = '375px';24 html.style.overflow = 'hidden';25 html.style.overflowY = 'auto';26 } else {27 // 内容自适应 - 设置zoom。通过zoom来缩放界面,在ipad的safari浏览器等会存在字体无法缩放的兼容问题。28 document.documentElement.style.zoom = zoomValue;29 }30 // 内容自适应 - 设置viewport,整体okay。但是ipad的水平滚动条无法解决31 // var viewport = document.querySelector("meta[name=viewport]");32 // viewport.content = "width=device-width,initial-scale=" + zoomValue + ", maximum-scale=" + zoomValue + ", minimum-scale=" + zoomValue + ",user-scalable=no, minimal-ui"33 }此方案的一些小遗留问题:
ipad不支持position:fixed,所以无法实现标题栏置顶等功能
微信浏览器,横竖屏切换时,有些机型在打开一瞬间,有空白问题
参考:
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69959503/viewspace-2722520/ ,如需转载,请注明出处,否则将追究法律责任。