Web移动端 自适应缩放界面
在开发App端的网页时,要适配iphone、ipad、ipod、安卓等各种机型,一般是直接使用em、px转em、界面缩放。
本章是通过将界面缩放,等比例显示在各机型上。过程中遇到了些问题和大坑~
方案一 设置tranform/scale
首先设置内容固定宽度、自动高度(以下举例)
添加一段设置zoom值的函数:
getScript() {
return `
const zoomValue=window.innerWidth / 375;
document.documentElement.style.transform="scale("+zoomValue+")";
document.documentElement.style.transformOrigin="left top";
`;
}
注:
以上也可以直接写script,我上面返回一段html是因为项目是通过服务端渲染的。
样式的设置必须在界面加载之前,否则会因界面显示变更出现闪现问题。
因为添加了服务端渲染,所以无法在界面一开始初始时,无法获取window、document等对象。而上面html的注入,对服务端渲染机制的一个黑科技~
上面的方案完成后,看看效果。然后坑出来了:
- 项目设置的absolue元素width 100%失效了 -- 可以设置固定的宽度解决
- 弹框position=fixed位置飞到天边去了 -- 这个无法规避
网上找到了一篇文章 CSS3 transform对普通元素的N多渲染影响 ,介绍了transform的一堆坑。
我这个项目一些布局需要position=fixed,所以tranform不适合~放弃
这个坑的其它介绍可以参考下:
总结:
- position:fixed不支持,所以想做标题栏置顶,上面方案是无法实现的。
- ipad有遗留问题:微信浏览器,横竖屏切换时,有些机型在打开一瞬间,横向拖动有空白问题。这个问题无法处理~
- 以上方案因为使用了scale,同时窗口的宽高window.innerHeight无法准确获取,需要除以比例,详见windowSizeWithScaleHelper
方案二 设置zoom
在上一个方案的基础上,尝试zoom缩放:
getScript() {
return `
const zoomValue=window.innerWidth / 375;
document.documentElement.style.zoom = zoomValue;
`;
}
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。
发现可以处理,没毛病!但是也有些缺陷,没办法在一开始处理字体,因为元素还没有初始化,而等界面加载后再刷字体大小,界面会闪现一次。
方案三 设置viewport-scare
在html中添加默认viewport:
<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更新:
getScript() {
return `
const zoomValue=window.innerWidth / 375;
var viewport = document.querySelector("meta[name=viewport]");
viewport.content="width=device-width,initial-scale="+zoomValue+", maximum-scale="+zoomValue+", minimum-scale="+zoomValue+",user-scalable=no, minimal-ui"
`;
}
运行代码,emmm,有一些小问题。
- margin:auto,在某些布局下会让页面偏移 -- 删除就好
- 设置background-image的区域,背景图片并没有填充满 -- 添加width:100%解决
- position:fixed,宽高显示有问题 -- 设置固定宽度,比如375px,固定高度;如果需要全屏,可以使用height: 100vh
fixed布局建议:以弹框为例
添加fixed布局的容器,水平竖直方向靠边距离分别设置一个就行了,left:0,bottom:0。
然后添加absolute布局的内容容器.如果需要居中,可以在js中设置bottom=window.innerHeight / 2 - 元素的高度/2
总结:
- 以上方案不支持fixed布局,修改完成后,ipad的水平滚动条依然存在,无法解决
兼容适配
采用第二个zoom缩放方案,同时对ipad机型特殊处理,另外采用scale缩放方案。
完整代码如下:
1. 初始化适配(支持服务端渲染)
html-header添加script
{/* app contentAutoFit */}
<script dangerouslySetInnerHTML={{ __html: this.getZoomScript() }}></script>
自适应可执行代码文本
//返回自适应html字符串
getZoomScript() {
return `
const zoomValue = window.innerWidth / 375;
const userAgentInfo = window.clientInformation.appVersion;
//如果是ipad
if (userAgentInfo.indexOf("iPad") != -1 || userAgentInfo.indexOf("Macintosh") != -1) {
//内容自适应 - 设置transform-scale。
//fixed布局时需要修改下left/margin-left等,同时窗口的宽高无法准确获取,需要除以比例,详见windowSizeWithScaleHelper
//ipad有遗留问题:微信浏览器加载时,横竖屏切换一瞬间,有空白问题。不过可以忽略~
document.documentElement.style.transform = "scale(" + zoomValue + "," + (zoomValue < 1 ? 1 : zoomValue) + ")";
document.documentElement.style.transformOrigin = "left top";
var html = document.querySelector("html");
html.style.width = '375px';
html.style.overflow = 'hidden';
html.style.overflowY = 'auto';
} else {
//内容自适应 - 设置zoom。通过zoom来缩放界面,在ipad的safari浏览器等会存在字体无法缩放的兼容问题。
document.documentElement.style.zoom = zoomValue;
}
// 内容自适应 - 设置viewport,整体okay。但是ipad的水平滚动条无法解决
// var viewport = document.querySelector("meta[name=viewport]");
// viewport.content = "width=device-width,initial-scale=" + zoomValue + ", maximum-scale=" + zoomValue + ", minimum-scale=" + zoomValue + ",user-scalable=no, minimal-ui"
`;
}
2. 添加加载及界面变更刷新机制
componentDidMount() {
window.onresize = this.adjustContentAutoFit;
//解决微信横竖屏问题
window.addEventListener("orientationchange", this.adjustContentAutoFit);
//解决加载过程中,切换横竖屏,导致界面没有适配的问题
this.adjustContentAutoFit();
}
componentWillUnmount() {
window.removeEventListener("orientationchange", this.adjustContentAutoFit);
}
//监听窗口尺寸变更,刷新自适应
adjustContentAutoFit() {
const zoomValue = window.innerWidth / 375;
const userAgentInfo = window.clientInformation.appVersion;
//如果是ipad
if (userAgentInfo.indexOf("iPad") != -1 || userAgentInfo.indexOf("Macintosh") != -1) {
//内容自适应 - 设置transform-scale。
//fixed布局时需要修改下left/margin-left等,同时窗口的宽高无法准确获取,需要除以比例,详见windowSizeWithScaleHelper
//ipad有遗留问题:微信浏览器,横竖屏切换时,有些机型在打开一瞬间,有空白问题。不过可以忽略~
document.documentElement.style.transform = "scale(" + zoomValue + "," + (zoomValue < 1 ? 1 : zoomValue) + ")";
document.documentElement.style.transformOrigin = "left top";
var html = document.querySelector("html") as HTMLElement;
html.style.width = '375px';
html.style.overflow = 'hidden';
html.style.overflowY = 'auto';
} else {
// 内容自适应 - 设置zoom。通过zoom来缩放界面,在ipad的safari浏览器等会存在字体无法缩放的兼容问题。
document.documentElement.style.zoom = zoomValue;
}
// 内容自适应 - 设置viewport,整体okay。但是ipad的水平滚动条无法解决
// var viewport = document.querySelector("meta[name=viewport]");
// viewport.content = "width=device-width,initial-scale=" + zoomValue + ", maximum-scale=" + zoomValue + ", minimum-scale=" + zoomValue + ",user-scalable=no, minimal-ui"
}
此方案的一些小遗留问题:
ipad不支持position:fixed,所以无法实现标题栏置顶等功能
微信浏览器,横竖屏切换时,有些机型在打开一瞬间,有空白问题
参考:
- IOS环境下固定定位position:fixed带来的问题与解决方案
- 小技巧css解决移动端ios不兼容position:fixed属性,无需插件
- 踩坑路上——IOS Safari浏览器下固定定位position:fixed带来的问题与解决方案
- iphone safari不支持position fixed的解决办法
Web移动端 自适应缩放界面的更多相关文章
- 用Rem来无脑还原Web移动端自适应的页面
(function (win,doc){ if (!win.addEventListener) return; var html=document.documentElement; function ...
- 有了这套flexible.js 移动端自适应方案,你就能在移动端的来去自如, (*^__^*)
flexible.js 移动端自适应方案 一,flexible.js 的使用方式: github地址:https://github.com/amfe/lib-flexible 官方文档地址:https ...
- 原创:CSS3技术-雪碧图自适应缩放与精灵动画方案
花了一个礼拜完成了慕课网定制的七夕主题效果,其中有一个没实现好的功能,就是雪碧图的自适应缩放 ps: 以下实现都是基于移动端的处理 原图如下: 人物是采用的是雪碧图,通过坐标绝对数据取值 问题很明显, ...
- 阻止pc端浏览器缩放js代码
阻止pc端浏览器缩放js代码 众所周知:移动端页面禁止用户缩放界面只需加上<meta name="viewport" content="user-scalable= ...
- finereport普通报表的移动端自适应方案
移动端报表呈现,首先要求的是页面随手机屏幕大小自动放缩(自适应),下面给出一个普通报表中的finereport移动端自适应方案,适用于finereport 7.1之前的版本. 首先,了解一下当前我们可 ...
- Openstack的web管理端相关
openstack的web管理端技术方面要关注的问题. 同步?异步 先说浏览器的同步和异步,我们知道的浏览器可以使用ajax实现异步请求,就是浏览器在请求数据的时候,我们管理员还能对浏览器就行其他操作 ...
- 基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用
在前面介绍了两篇关于我的基于MVC4+EasyUI技术的Web开发框架的随笔,本篇继续介绍其中界面部分的一些使用知识,包括控件的赋值.取值.清空,以及相关的使用. 我们知道,一般Web界面包括的界面控 ...
- 从web移动端布局到react native布局
在web移动端通常会有这样的需求,实现上中下三栏布局(上下导航栏位置固定,中间部分内容超出可滚动),如下图所示: 实现方法如下: HTML结构: <div class='container'&g ...
- 转--基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用
原文 http://www.cnblogs.com/wuhuacong/p/3317223.html 基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用 在前面介绍了两篇关于我的基 ...
随机推荐
- java实现古堡算式
** 古堡算式** 福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式: ABCDE * ? = EDCBA 他对华生说:"ABCDE应该代表不同的数字,问号也代表某个数字!" 华生 ...
- java实现第六届蓝桥杯显示二叉树
显示二叉树 题目描述 排序二叉树的特征是: 某个节点的左子树的所有节点值都不大于本节点值. 某个节点的右子树的所有节点值都不小于本节点值. 为了能形象地观察二叉树的建立过程,小明写了一段程序来显示出二 ...
- Python学习之求阶乘篇
描述 给定一个数n,范围为0≤n≤100,请你编程精确的求出n的阶乘n!. 输入 输入数据有多行,每行一个整数n,当n<0时输入结束. 输出 输出n的阶乘. 样例输入 1234-1 样例输出 1 ...
- Mac 制作 Linux 启动盘
本文原始地址:https://sitoi.cn/posts/28583.html 前期准备 一个 Mac 电脑 一个 U 盘(8GB 以上) 下载好 Linux 系统镜像(iso 文件) 具体步骤 挂 ...
- (十二)DVWA全等级SQL Injection(Blind)盲注--SQLMap测试过程解析
一.测试前分析 前文<DVWA全等级SQL Injection(Blind)盲注-手工测试过程解析> 通过手工测试的方式详细分析了SQL Injection(Blind)盲注漏洞的利用过程 ...
- 如何解决ubuntu 12.04重启后出现waiting for network configuration和网络标志消失问题
如何解决ubuntu 12.04重启后出现waiting for network configuration和网络标志消失问题 作为菜鸟的我在学着设置网络后,重启电脑后显示 waiting forne ...
- laravel模板使用
{{ $var }} - 打印内容 {{ $var or 'default' }} - 打印内容并带一个默认值 {{{ $var }}} - 打印转义内容 {{-- Comment --}} - 注释 ...
- Fabric网络节点发现及成员管理
一个新节点通过已知的节点加入到网络中,此时,它所知的网络节点信息是非常有限的,需要通过节点发现获知更多的节点,建立起足够的连接.另外,当一个新节点加入到网络时,原有网络节点也需要通过节点发现感知到新节 ...
- TensorFlow从0到1之TensorFlow优化器(13)
高中数学学过,函数在一阶导数为零的地方达到其最大值和最小值.梯度下降算法基于相同的原理,即调整系数(权重和偏置)使损失函数的梯度下降. 在回归中,使用梯度下降来优化损失函数并获得系数.本节将介绍如何使 ...
- 软件包,API,SDK的区别
参考资料: https://www.jianshu.com/p/cac186cb168b https://blog.csdn.net/snowin1994/article/details/806080 ...