移动端适配,h5网页,手机端适配兼容方案.可以显示真实的1px边框和12px字体大小,dpr浅析
以前写移动端都是用这段JS解决.
(function (doc, win) {
// 分辨率Resolution适配
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth >= 750) {
docEl.style.fontSize = 100 + 'px';
}else{docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';}
}
// Abort if browser does not support addEventListener
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
recalc();
})(document, window);
JS中设计稿的大小可以随便改,我这里用的设计稿都是750的,将750尺寸下,根元素font-size大小设置成100px,用这个JS可以实现页面随根元素的font-size大小而改变,也就是rem写法.当设计稿中元素大小为100px时候,只要在css中设置成1rem就可以.计算很方便,这样写确实简单.
但这个JS有一些很难受的弊端,其一在现在iphone和其它手机中,dpr值都为2或者3,这样会出现移动端1px这个不是1px的难题,会是2px 3px的大小.这样会导致给一个文字加边框文字会塌下去的问题.
字体大小在dpr=2的iphone设备只能设置到24px,原理如下375*24/750=12,浏览器最小设置字体大小为12.ipone5的真实大小是375pt.也就是真实设计稿750px的一半大.
dpr=3的设备也只能设置到12*750/414=21.74px.所以弊端不少.ipone6plus的真实大小是414pt.
不懂 dpr pt px的可以去网上问问,理解就可以.
前段时间看到网上有个hotcss解决方案,我研究了一下代码.代码如下(做了简单的修改,原因下文中有):
(function( window , document ){
'use strict';
//给hotcss开辟个命名空间,别问我为什么,我要给你准备你会用到的方法,免得用到的时候还要自己写。
var hotcss = {};
(function() {
//根据devicePixelRatio自定计算scale
//可以有效解决移动端1px这个世纪难题。
var viewportEl = document.querySelector('meta[name="viewport"]'),
hotcssEl = document.querySelector('meta[name="hotcss"]'),
dpr = window.devicePixelRatio || 1,
maxWidth = 750,//最大显示尺寸
designWidth = 0;
dpr = dpr >= 3 ? 3 : ( dpr >=2 ? 2 : 1 );
//允许通过自定义name为hotcss的meta头,通过initial-dpr来强制定义页面缩放
if (hotcssEl) {
var hotcssCon = hotcssEl.getAttribute('content');
if (hotcssCon) {
var initialDprMatch = hotcssCon.match(/initial\-dpr=([\d\.]+)/);
if (initialDprMatch) {
dpr = parseFloat(initialDprMatch[1]);
}
var maxWidthMatch = hotcssCon.match(/max\-width=([\d\.]+)/);
if (maxWidthMatch) {
maxWidth = parseFloat(maxWidthMatch[1]);
}
var designWidthMatch = hotcssCon.match(/design\-width=([\d\.]+)/);
if (designWidthMatch) {
designWidth = parseFloat(designWidthMatch[1]);
}
}
}
document.documentElement.setAttribute('data-dpr', dpr);
hotcss.dpr = dpr;
document.documentElement.setAttribute('max-width', maxWidth);
hotcss.maxWidth = maxWidth;
if( designWidth ){
document.documentElement.setAttribute('design-width', designWidth);
hotcss.designWidth = designWidth;
}
var scale = 1 / dpr,
content = 'width=device-width, initial-scale=' + scale + ', minimum-scale=' + scale + ', maximum-scale=' + scale + ', user-scalable=no';
if (viewportEl) {
viewportEl.setAttribute('content', content);
} else {
viewportEl = document.createElement('meta');
viewportEl.setAttribute('name', 'viewport');
viewportEl.setAttribute('content', content);
document.head.appendChild(viewportEl);
}
})();
hotcss.px2rem = function( px , designWidth ){
//预判你将会在JS中用到尺寸,特提供一个方法助你在JS中将px转为rem。就是这么贴心。
if( !designWidth ){
//如果你在JS中大量用到此方法,建议直接定义 hotcss.designWidth 来定义设计图尺寸;
//否则可以在第二个参数告诉我你的设计图是多大。
designWidth = parseInt(hotcss.designWidth , 10);
}
return parseInt(px,10)*750/designWidth/100;
}
hotcss.rem2px = function( rem , designWidth ){
//新增一个rem2px的方法。用法和px2rem一致。
if( !designWidth ){
designWidth = parseInt(hotcss.designWidth , 10);
}
//rem可能为小数,这里不再做处理了
return rem*100*designWidth/750;
}
hotcss.mresize = function(){
//对,这个就是核心方法了,给HTML设置font-size。
var innerWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth;
if( hotcss.maxWidth && (innerWidth/hotcss.dpr > hotcss.maxWidth) ){
innerWidth = hotcss.maxWidth*hotcss.dpr;
}
if( !innerWidth ){ return false;}
document.documentElement.style.fontSize = ( innerWidth*100/750 ) + 'px';//设计尺寸750 根元素为100px 便于计算
hotcss.callback && hotcss.callback();
};
hotcss.mresize();
//直接调用一次
window.addEventListener( 'resize' , function(){
clearTimeout( hotcss.tid );
hotcss.tid = setTimeout( hotcss.mresize , 33 );
} , false );
//绑定resize的时候调用
window.addEventListener( 'load' , hotcss.mresize , false );
//防止不明原因的bug。load之后再调用一次。
setTimeout(function(){
hotcss.mresize();
//防止某些机型怪异现象,异步再调用一次
},333)
window.hotcss = hotcss;
//命名空间暴露给你,控制权交给你,想怎么调怎么调。
})( window , document );
这样写出来的方案就考虑到了dpr值的影响,以上问题都可以解决掉,他们的CSS是用sass实时去编译计算的,
宽高这么写width:px2rem(182);height:px2rem(53);
下边这个函数就是用来解决这个算法的.
@function px2rem( $px ){
@return $px*320/$designWidth/20 + rem;
}
他的JS我稍微做了修改,因为老去写px2rem()这个方法烦的很,所以我把里边计算根元素字体大小这句改成如下
document.documentElement.style.fontSize = ( innerWidth*100/750 ) + 'px';//设计尺寸750 根元素为100px 便于计算
这样做的原因如下,我的设计稿一直都是750px,在这个尺寸下我将根元素字体大小设置成100px,这样我设计稿上的元素高是98px的时候,我直接设置成0.98rem;这样简单的计算一下,速度很快,也不会去写px2rem()这个方法;
如果写个简单活动页面,也可以不用sass 老去监听编译,测试也麻烦.直接口算简单易用.
如果你的设计稿是720,这句话应该为
document.documentElement.style.fontSize = ( innerWidth*100/720 ) + 'px';
移动端适配,h5网页,手机端适配兼容方案.可以显示真实的1px边框和12px字体大小,dpr浅析的更多相关文章
- 关于手机端适配的问题(rem,页面缩放)
关于手机端适配的问题(rem,页面缩放) 96 进击的小前端 关注 2018.02.02 13:57 字数 320 阅读 19评论 0喜欢 0 相信很多和会和我碰到一样的情况,就是你用rem去写移动端 ...
- 移动端调试神器vconsole,手机端网页的调试工具Eruda
移动端调试神器vconsole,手机端网页的调试工具Eruda 移动端中使用 vConsole调试 移动端调试工具vconsole安装Git地址:https://github.com/WechatFE ...
- PC端页面转换成手机端页面的分辨率问题的理解
PC端页面转换成手机端页面的分辨率问题的理解 px vw rem 假如就以a4纸模式为设计图 ,在a3纸模式中设计,然后设计出来展示在不同的a4纸模式上 通常是 750px -> 100vw / ...
- h5 手机端适配问题汇总
1.uc手机浏览器竟然没有 sessionstorage 醉了 2.opera 浏览器 能识别 a标签中href的 javascript:; 为网址 , 55555 3.safari 的弹框如 ...
- 【web前端】移动端控制台插件,手机端页面查看相关页面控制台信息
一般调试手机端页面时,基本是在PC端使用手机模式进行断点或console调试.或查看有用的控制台信息的,但依旧有部分功能无法在PC端调试,经常需要使用alert进行断点,然后在手机端看效果,但是这样并 ...
- h5实现手机端等级进度条
h5实现等级进度条 需求如下: 实现一个动画进度条,页面一打开实现一个进度条动画,因为App这个页面会经常改,所以没有使用原审Android或者IOS来实现,希望通过H5来做: 服务器端返回如下数据: ...
- H5页面手机端禁止缩放的正确方式
H5页面禁止手机端缩放是个常见问题了 首先说meta方式 <meta content="width=device-width, initial-scale=1.0, maximum-s ...
- layUI中layDate控件兼容性问题(手机端没有效果,不显示)
使用layDate插件发现在PC端无问题,然而在适配移动端时,发现点击input时,laydate渲染出的时间控件有时候没有反应,后发现只需在render里加入trigger: 'click',即可以 ...
- AngularJs 中使用OpenLayer例子,手机端地图加载不显示问题
var map, toolip, overlay; var layer = new ol.layer.Vector(); var imgLayer = ...
随机推荐
- python 获取大乐透中奖结果
实现思路: 1.通过urllib库爬取http://zx.500.com/dlt/页面,并过滤出信息 2.将自己的买的彩票的号与开奖号进行匹配,查询是否中奖 3.将中奖结果发生到自己邮箱 caipia ...
- Altium Designer16设置GND和VCC线宽规则的一种操作方法及注意事项
昨天看到学弟在画电路板,看到他设置电源线线宽时出了一点问题,设置的规则最开始有作用,后来重新从原理图导入更新PCB时,电源线变绿,规则设置点更新也没有用.接下来是操作步骤: 第一步:点击Design- ...
- SQL Labs刷题补坑记录(less1-less30)
补坑加1,这几天快速刷一下sqllabs 来巩固下sql注入基础吧,也算是把很久以前没刷的过一遍,do it! 第一部分: LESS1: 直接报错,有回显的注入, http://localhost/s ...
- Go中的反射reflect
前面我们在学习到struct结构体的时候,因为结构体中的字段首字母大写,而我们想把json文件映射到该结构体上时,需要在在结构体字段后面加上json标签,表明结构体字段和json字段的映射关系.这其中 ...
- requestAnimationFrame 兼容方案
[toc] 编写涉及:css, html, js 在线演示codepen html代码 <div class="roll-box"> <div class=&qu ...
- 算法与数据结构基础 - 双指针(Two Pointers)
双指针基础 双指针(Two Pointers)是面对数组.链表结构的一种处理技巧.这里“指针”是泛指,不但包括通常意义上的指针,还包括索引.迭代器等可用于遍历的游标. 同方向指针 设定两个指针.从头往 ...
- Duilib的圆环形 进度条 实现(网易云信版本)
/** @file CircleProgress.h* @brief 圆环型进度条控件,圆环中间可以有文本(如85%)* @copyright (c) 2019-2022, NetEase Inc. ...
- go 学习笔记之值得特别关注的基础语法有哪些
在上篇文章中,我们动手亲自编写了第一个 Go 语言版本的 Hello World,并且认识了 Go 语言中有意思的变量和不安分的常量. 相信通过上篇文章的斐波那契数列,你已经初步掌握了 Go 语言的变 ...
- 神经网络优化算法:Dropout、梯度消失/爆炸、Adam优化算法,一篇就够了!
1. 训练误差和泛化误差 机器学习模型在训练数据集和测试数据集上的表现.如果你改变过实验中的模型结构或者超参数,你也许发现了:当模型在训练数据集上更准确时,它在测试数据集上却不⼀定更准确.这是为什么呢 ...
- ElasticSearch实战系列一: ElasticSearch集群+Kinaba安装教程
前言 本文主要介绍的是ElasticSearch集群和kinaba的安装教程. ElasticSearch介绍 ElasticSearch是一个基于Lucene的搜索服务器,其实就是对Lucene进行 ...