的缓和方案,移动端常见难题管理

作者: 前端知识  发布:2019-09-14

再谈 Retina 下 1px 的施工方案

2017/07/25 · CSS · 1px

原稿出处: 大漠   

在互联英特网关于于1px边框的建设方案已经有很各个了,自从使用Flexible库之后,再也尚无纠结有关于1px连带的主题素材。由于近日在虚构新的移位端适配方案,也等于遗弃Flexible库,笔者只好思量重新管理1px的方案。为此为小编自个儿也重撸了有的1px的消除方案,整理出来,希望对有亟待的同室有扶助。

微信浏览器顾客调治字体大小后页面矬了,怎么阻止顾客调治

//以下代码可使Android机页面不再受用户字体缩放强制改变大小,但是会有1S左右延时,期间可以考虑loading来处理
if (typeof(WeixinJSBridge) == "undefined") {
    document.addEventListener("WeixinJSBridgeReady", function (e) {
        setTimeout(function(){
            WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize':0}, function(res){
                alert(JSON.stringify(res));
            })
        }, 0)
    });
}else{  
    setTimeout(function(){
        WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize':0}, function(res){
            alert(JSON.stringify(res));
        })
    }, 0)   
}

//IOS下可使用 -webkit-text-size-adjust禁止用户调整字体大小
body { -webkit-text-size-adjust:100%!important; }
//最好的解决方案:最好使用rem或百分比布局

Flexible方案

Flexible方案已不是怎么秘密的方案了,借助JavaScript来动态修改meta标签中viewport中的initial-scale的值,然后遵照dpr修改html中的font-size值,再使用rem来管理。有关于那上头的详实使用能够翻阅后期整理的篇章《选择Flexible达成手淘H5页面的终极适配》。

可是话说回来,那么些方案最近只管理了iOS的dpr2的境况,别的的都并未有拍卖,也正是说不辅助Android和drp=3的图景。对于追求完善的同窗来说,那是力不从清热生津受的。

有标题,总是有建设方案的,有同学做过地点的详实探究。那么随着其思路也再次撸了三遍。先回到Fleible中,其落到实处原理,大家都晓得的。让viewport放大为device-widthdpr倍数,然后缩短1/dpr倍显示。

对于viewport的盘算理论上是那般的:

viewport金沙澳门官网网址 ,的width没安装的话,暗许是980px,那上头的事无巨细介绍可以阅读《Configuring the Viewport》一文;但万一设置了initial-scaleviewport=device-width/scale;同期还安装了widthinitial-scale,则会取min-width,即采用那七个不大的值。详细的牵线能够翻阅《Preliminary meta viewport research》一文。

接下去看看各类设施下的境况。首先采用JavaScript总结出scale的值:

var scale = 1 / window.devicePixelRation;

1
var scale = 1 / window.devicePixelRation;

head中的meta标签设备:

<meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no"/>

1
  <meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no"/>

iPhone5viewportwidth=640px,得到的meta值:

<meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no"/>

1
  <meta name="viewport" content="initial-scale=scale,maximum-scale=scale,minimum-scale=scale,user-scalable=no"/>

切合大家预料所需的结果。

iPhone6 Plus也是两全的:

<meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no"/>

1
  <meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no"/>

再来看多少个Android的配备。比如米3,它的dpr=3viewportwidth=1080,获得的值也是我们希望的:

<meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no"/>

1
  <meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333,user-scalable=no"/>

在米2中,它的dpr=2viewportwidth=720,效果也是OK的。

<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"/>

1
  <meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"/>

看样子这里时,大家兴许都会认为完美,没有需求纠结啥,事实上在米2和米3中,看到的都是安装暗许的浏览器、UC和Chrome浏览器的结果。回过头来再看WebView,那就出标题了。当Webview为360时,线照旧也是粗的,这里测量检验,开掘user-scalable=no会使viewport的值等于device-width。那么大家越发去掉user-scalable=no抑或设置user-scalable=yes

<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/> <meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333"/>

1
2
  <meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/>
  <meta name="viewport" content="initial-scale=0.3333333333,maximum-scale=0.3333333333,minimum-scale=0.3333333333"/>

如此设置,在iOS、米3的Webview下都能博得预期效果,可是在米第22中学的Webview依然有毛病,页面会被放大。问题是出在于米2的Webview的viewportwidth=490px,是由默许的980px缩放0.5后的值。而米2的device-width=360,所以就能产出撑开放不下的情景。

米2的Webview怎么做? 想起还应该有个被webkit在二〇一二年二月舍弃的性质target-densitydpi=device-dpi,此属性是前面Android对viewport标签的恢宏,arget-densitydpi的值有: device-dpi, high-dpi, medium-dpi, low-dpi三个。对于One plus2的Webview才出现的主题材料估摸只可以非标准的性质来hack试试,densitydpi=device-dpi会让页面根据设备自己的dpi来渲染。

<meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/>

1
  <meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/>

测量试验其余都例行,就HTC2的Webview会出现略微边框偶然冒出若隐若现,原本是此时页面包车型地铁viewport=980,densitydpi=device-dpi以设备实际的dpi显示后,scale的翻番变为360/980,这种场所压缩下去大概就疑似此残了~~

想艺术让OPPO2的缩放比为BlackBerry的dprviewport何以能造成2*360=720呢,试试user-scalable=no再度加回去试试,终于,华为2的Webview下冒出了纤弱的线条。

<meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"/>

1
  <meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"/>

测验了下对One plus连串、三星(Samsung)类别、OPPO等主流机型的熏陶,平常!

别开心的太早,在大天朝下,不唯有有这一个道具。还会有VIVO之类的无绳电话机,他们的dpr=3,他们的viewport=980px,裁减为本来的1/3后,效果就不是大家所要的了。除却,还大概有一对器械,它的dpr很变态,比如VIVO的Android4.1.2,它的dpr=1.5,而其viewport也等于980,收缩为本来的1/1.5 = 2 / 3,宽度就改为了980 * 2 / 3 = 653.333,获得的效能也是力所不及直视的。当然还或者有一部分大家所不知情的道具呢?这么些能够经过Device Metrics网址来查看出设备相关的参数:

金沙澳门官网网址 1

那也是当初Fleible扬弃医疗Android的来由。

但总的来讲,其根本原因是均等的,viewport的暗中认可宽度照旧是980initial-scale等的安装不能够改观viewport的规范化总结。看来这一个非主流机型上只好通过width来更动了。意料之中,设置如下就可以

<meta name="viewport" content="target-densitydpi=device-dpi,width=device-width,user-scalable=no"/>

1
  <meta name="viewport" content="target-densitydpi=device-dpi,width=device-width,user-scalable=no"/>

更为测验开掘绝大多数Android机器用上面包车型地铁vieport安装也全然可以兑现1px的真正效果。但是新webkit下已经移除了对target-densitydpi=device-dpi的帮衬。所以主流Android还是用职业的设置上述initscale=scale,因而最后的方案是主流的装置安装viewport

<meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/>

1
  <meta name="viewport" content="densitydpi=device-dpi,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5"/>

安装以上viewport要么不可能改换私下认可980为宽度的viewport的肥猪流设备(如摩托罗拉,云os等),设置如下:

<meta name="viewport" content="target-densitydpi=device-dpi,width=device-width,user-scalable=no"/>

1
  <meta name="viewport" content="target-densitydpi=device-dpi,width=device-width,user-scalable=no"/>

进而,最终的落到实处代码如下:

metaEl.setAttribute('content', 'target-densitydpi=device-dpi,user-scalable=no,initial-scale=' scale ',maximum-scale=' scale ', minimum-scale=' scale); //不通过参与具体设备的白名单,通过此特征检测 docEl.clientWidth == 980 //initial-scale=1不可能省,因为地点安装为其余的scale了,须求复位回来 if(docEl.clientWidth == 980) { metaEl.setAttribute('content', 'target-densitydpi=device-dpi,width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1'); }

1
2
3
4
5
6
metaEl.setAttribute('content', 'target-densitydpi=device-dpi,user-scalable=no,initial-scale=' scale ',maximum-scale=' scale ', minimum-scale=' scale);
//不通过加入具体设备的白名单,通过此特征检测 docEl.clientWidth == 980
//initial-scale=1不能省,因为上面设置为其他的scale了,需要重置回来
if(docEl.clientWidth == 980) {
    metaEl.setAttribute('content', 'target-densitydpi=device-dpi,width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1');
}

减去的代码能够点击这里下载。这几个也得以说是Flexible的进级版本吧(另外感兴趣的能够看看npm上的postcss-adaptive)。但亦非小编所要求的方案,小编的末梢方案是甩掉Flexible。

纵然你对上边包车型客车方案不是很乐意,你能够依照那篇小说《Mobile Web: Logical Pixel vs Physical Pixel》提供的减轻方案,整理出符合本身的方案。原理和日前介绍的平等。

iPhone系列的viewport

<meta name="viewport" content="width=device-width initial-scale=0.5 maximum-scale=0.5 user-scalable=no"/>

1
  <meta name="viewport" content="width=device-width initial-scale=0.5 maximum-scale=0.5 user-scalable=no"/>

Android系列的viewport:

<meta name="viewport" content="width=device-width target-densityDpi=device-dpi initial-scale=0.5 maximum-scale=0.5 user-scalable=no"/>

1
  <meta name="viewport" content="width=device-width target-densityDpi=device-dpi initial-scale=0.5 maximum-scale=0.5 user-scalable=no"/>

一样为了完成上述的供给,通过JavaScript来拍卖:

if (window.devicePixelRatio === 1) { if (window.innerWidth === 2 * screen.width || window.innerWidth === 2 * screen.height) { el = document.getElementById('viewport'); el.setAttribute('content', 'width=device-width target-densityDpi=device-dpi ' 'initial-scale=1 maximum-scale=1 user-scalable=no'); document.head.appendChild(el); width = window.innerWidth; height = window.innerHeight; if (width === 2 * screen.width) { width /= 2; height /= 2; } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (window.devicePixelRatio === 1) {
    if (window.innerWidth === 2 * screen.width ||
        window.innerWidth === 2 * screen.height) {
        el = document.getElementById('viewport');
        el.setAttribute('content', 'width=device-width target-densityDpi=device-dpi '
            'initial-scale=1 maximum-scale=1 user-scalable=no');
        document.head.appendChild(el);
        width = window.innerWidth;
        height = window.innerHeight;
        if (width === 2 * screen.width) {
            width /= 2;
            height /= 2;
        }
    }
}

是还是不是深感他们特别左近。感兴趣不仿试试。

荧屏旋转的事件和样式

function orientInit(){
    var orientChk = document.documentElement.clientWidth > document.documentElement.clientHeight?'landscape':'portrait';
    if(orientChk =='lapdscape'){
        //这里是横屏下需要执行的事件
    }else{
        //这里是竖屏下需要执行的事件
    }
}
orientInit();
window.addEventListener('onorientationchange' in window?'orientationchange':'resize', function(){
    setTimeout(orientInit, 100);
},false)
//CSS处理
//竖屏时样式
@media all and (orientation:portrait){   }
//横屏时样式
@media all and (orientation:landscape){   }

.5px方案

二零一五年的WWDC大会中,Ted O’Conor在享受“设计响应的Web体验” 核心时涉嫌关于Retina Hairlines一词,也正是Retina非常细的线:

在Retina屏上唯有呈现1物理像素的边框,开辟者应该如何管理吧?

实在其想表明的是iOS8下1px边框的建设方案。1px的边框在devicePixelRatio = 2的Retina屏下会展现成2px,在三星6 Plus下居然会显得成3px

幸亏,时代总是提升的,在iOS8下,苹果连串都早已支撑0.5px了,那么意味着在devicePixelRatio = 2时,我们能够凭仗媒体询问来拍卖:

.border { border: 1px solid black; } @media (-webkit-min-device-pixel-ratio: 2) { .border { border-width: 0.5px } }

1
2
3
4
5
6
7
8
9
.border {
    border: 1px solid black;
}
 
@media (-webkit-min-device-pixel-ratio: 2) {
    .border {
        border-width: 0.5px
    }
}

但在iOS7之下和Android等别的系统里,0.5px将会被展现为0px,那么我们就必要想出办法消除,说其实一点正是找到哈克。

先是我们能够通过JavaScript来剖断UA,固然是iOS8 ,则输出类名hairlines,为了防止重绘,把这段代码增添在``之前:

if (/iP(hone|od|ad)/.test(navigator.userAgent)) { var v = (navigator.appVersion).match(/OS (d )_(d )_?(d )?/), version = parseInt(v[1], 10); if(version >= 8){ document.documentElement.classList.add('hairlines') } }

1
2
3
4
5
6
7
if (/iP(hone|od|ad)/.test(navigator.userAgent)) {
    var v = (navigator.appVersion).match(/OS (d )_(d )_?(d )?/),
        version = parseInt(v[1], 10);
    if(version >= 8){
        document.documentElement.classList.add('hairlines')
    }
}

除此而外判读UA之外,还足以因而JavaScript来判别是或不是帮忙0.5px边框,假设协助的话,同样输出类名hairlines

if (window.devicePixelRatio && devicePixelRatio >= 2) { var testElem = document.createElement('div'); testElem.style.border = '.5px solid transparent'; document.body.appendChild(testElem); if (testElem.offsetHeight == 1){ document.querySelector('html').classList.add('hairlines'); } document.body.removeChild(testElem); }

1
2
3
4
5
6
7
8
9
if (window.devicePixelRatio && devicePixelRatio >= 2) {
    var testElem = document.createElement('div');
    testElem.style.border = '.5px solid transparent';
    document.body.appendChild(testElem);
    if (testElem.offsetHeight == 1){
        document.querySelector('html').classList.add('hairlines');
    }
    document.body.removeChild(testElem);
}

看待于第一种艺术,这种办法的可信赖性越来越高一些,可是须要把JavaScript放在body标签内,绝对来讲会有一对重绘,个人建议是用第一种格局。

以此方案不能包容iOS8之下和Android的器具。假设急需宏观的匹配,能够设想和方案一结合在协同管理。只是相比蛋疼。当然除了和Flexible方案组成在一起之外,还能思虑和上面的方案组合在联合利用。

audio元素和video成分在ios和andriod中不可能自动播放

1.<audio src="music/bg.mp3" autoplay loop controls>你的浏览器还不支持哦</audio>
2.<audio controls="controls"> 
    <source src="music/bg.ogg" type="audio/ogg"></source>
    <source src="music/bg.mp3" type="audio/mpeg"></source>
    优先播放音乐bg.ogg,不支持在播放bg.mp3
</audio>
//JS绑定自动播放(操作window时,播放音乐)
$(window).one('touchstart', function(){
    music.play();
})
//微信下兼容处理
document.addEventListener("WeixinJSBridgeReady", function () {
    music.play();
}, false);
//小结
//1.audio元素的autoplay属性在IOS及Android上无法使用,在PC端正常
//2.audio元素没有设置controls时,在IOS及Android会占据空间大小,而在PC端Chrome是不会占据任何空间

border-image

border-image是三个很奇妙的脾气,Web开辟人士借助border-image的九宫格个性,能够很好的施用到化解1px边框中。使用border-image解决1px我们供给二个特定的图片,那张图纸要顺应您的要求,可是它长得像下图:金沙澳门官网网址 2

 

其实利用的时候:

border-width: 0 0 1px 0; border-image: url(linenew.png) 0 0 2 0 stretch;

1
2
border-width: 0 0 1px 0;
border-image: url(linenew.png) 0 0 2 0 stretch;

上边的职能也仅达成了底层边框border-bottom1px的效果。之所以选取的图片是2px的高,上有些的1px水彩为透明,下有些的1px运用的视觉规定的border颜色。但万一大家边框头部和最上部都急需border时,需求做一下图纸的调度:

金沙澳门官网网址 3

border-width: 1px 0; border-image: url(linenew.png) 2 0 stretch;

1
2
border-width: 1px 0;
border-image: url(linenew.png) 2 0 stretch;

到近期甘休,大家早已能在Samsung上海展览中心现1px边框的效劳。不过大家也开采这么的艺术在非视网膜荧屏上会出现border不显得的现象。为了缓慢解决那一个难点,能够依赖媒体询问来拍卖:

.border-image-1px { border-bottom: 1px solid #666; } @media only screen and (-webkit-min-device-pixel-ratio: 2) { .border-image-1px { border-bottom: none; border-width: 0 0 1px 0; border-image: url(../img/linenew.png) 0 0 2 0 stretch; } }

1
2
3
4
5
6
7
8
9
10
.border-image-1px {
    border-bottom: 1px solid #666;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
    .border-image-1px {
        border-bottom: none;
        border-width: 0 0 1px 0;
        border-image: url(../img/linenew.png) 0 0 2 0 stretch;
    }
}

不管是独有一边的边框(比方示例中的尾部边框),依旧前后都有边框,我们都亟需对图纸做相应的拍卖,除些之外,如若边框的水彩做了变化,那么也亟需对图纸做处理。那样亦不是八个很好的技术方案。

重力影响事件

// 运用HTML5的deviceMotion,调用重力感应事件
if(window.DeviceMotionEvent){
    document.addEventListener('devicemotion', deviceMotionHandler, false)
}
var speed = 30;
var x = y = z = lastX = lastY = lastZ = 0;
function deviceMotionHandler(eventData){
    var acceleration = event.accelerationIncludingGravity;
    x = acceleration.x;
    y = acceleration.y; 
    z = acceleration.z;
    if(Math.abs(x-lastX)>speed || Math.abs(y-lastY)>speed || Math.abs(z-lastZ)>speed ){
        //这里是摇动后要执行的方法 
        yaoAfter();
    }
    lastX = x;
    lastY = y;
    lastZ = z;
}
function yaoAfter(){
    //do something
}

本文由金沙澳门官网发布于前端知识,转载请注明出处:的缓和方案,移动端常见难题管理

关键词: 金沙澳门官网

上一篇:探究一些幽默的CSS标题
下一篇:没有了