遇到的兼容性问题

442 阅读9分钟

在图片上使用 animation 改变 透明度 位移等属性, 会在有些屏幕上出现图片模糊的现象

出现的原因:是因为transform: translate(-50%,-50%), rem 等单位在计算的时候,因为出现了多位小数,导致此问题。

解决办法:

  • 可以设置固定的尺寸
  • transform: translate3d(0,0,0) 有奇效

H5适配方案和常遇见兼容性处理

目前主要的适配方案:

  • 对界面进行等比例缩放
  • 百分比实现页面适配
  • 通过媒体查询的方式即CSS3的 meida queries
  • 根据css的媒体查询动态设置根部html字体大小 + rem 实现适配
  • 使用js+viewport动态设置手动适配rem

一、对界面进行等比例缩放

原理: 这种方式属于有一种暴力适配,即通过计算设计人员给出的设计稿的尺寸和设备的真实尺寸,将这个比值作为缩放比赋值meta标签,但是这种情况下往往会出现字体和图片的失真或者锐化。

实现方式:

/*以下代码通过缩放方式实现为不同屏幕下适配设计稿尺寸js(不推荐)*/
  function flex(designWidth){
    let phoneScale = parseInt(window.screen.width) / designWidth;
    document.write('<meta name="viewport" content="width=' + designWidth + ',minimum-scale=' + phoneScale + ',maximum-scale=' + phoneScale + ',user-scalable=no">');
  };

实例;游戏学院主站点在移动端访问 : game.academy.163.com/

二、用百分比实现页面的适配

适用范围: 适合页面内容结构均匀分配,固定高度,结构不是很复杂,注意要设置viewport视口内容宽度等于设备的宽度

flex适配:同样是适合页面内容结构均匀分配,固定高度,注意要设置viewport视口内容宽度等于设备的宽度 老版本的display:box与新版本的display:flex都可以实现页面的自适应

三、媒体查询的方式即CSS3的 meida queries

原理:meida queries 布局方式,它主要是通过查询设备的宽度来执行不同的 css 代码,最终达到界面的配置

核心语法:

@media screen and (max-width: 600px) { /*当屏幕尺寸小于600px时,应用下面的CSS样式*/
  /*你的css代码*/
}

优点:

  • media query可以做到设备像素比的判断,方法简单,成本低,特别是对移动和PC维护同一套代码的时候。目前像Bootstrap等框架使用这种方式布局
  • 图片便于修改,只需修改css文件
  • 调整屏幕宽度的时候不用刷新页面即可响应式展

缺点:

  • 代码量比较大,维护不方便
  • 为了兼顾大屏幕或高清设备,会造成其他设备资源浪费,特别是加载图片资源
  • 为了兼顾移动端和PC端各自响应式的展示效果,难免会损失各自特有的交互方式

四、根据css的媒体查询动态设置根部html字体大小 + rem 实现适配

html{
    max-width: 640px;
    margin: 0px auto;
    font-size: 100px;
}

@media only screen and (max-width: 414px){
 html{
        font-size: 64px;
    }
}
@media only screen and (max-width: 375px){
    html{
        font-size: 58px;
    }
}
@media only screen and (max-width: 360px){
    html{
        font-size: 56px;
    }
}
@media only screen and (max-width: 320px){
    html{
        font-size: 50px;
    }
}
//不要忘记在head标签中添加如下视口设置
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

五、使用js+viewport动态设置手动适配rem (推荐使用)

原理: 动态计算根元素的font-size; 利用rem 实现适配

  getAdaptHtml = () => `
(function () {
  var setFontSize = function () {
    setTimeout(function () {
      var fontSize = (document.documentElement.clientWidth / 750) * 100;
      document.documentElement.style.fontSize = (fontSize > 100 ? 100 : fontSize ) + 'px';
      var realFontSize = parseFloat(window.getComputedStyle(document.documentElement).getPropertyValue('font-size'))
      if (Math.round(fontSize * 10000) !== Math.round(realFontSize * 10000)) {
        document.documentElement.style.fontSize = fontSize * (fontSize / realFontSize) > 100 ? '100' : fontSize * (fontSize / realFontSize) + 'px'
      }
    }, 100)
  }
  setFontSize();
  window.addEventListener('resize', setFontSize);
  window.addEventListener('orientationchange', setFontSize);
}())
`;

···

<meta
    name="viewport"
    // eslint-disable-next-line jsx-quotes
    content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"
    />
···

<script
    dangerouslySetInnerHTML={{ __html: this.getAdaptHtml() }}
    ></script>

附:

(1) 华为发布折叠屏官方适配方案

blog.csdn.net/weixin_3404…

(2) H5 页面适配iPhone X 方案

juejin.im/post/684490…

页面适配主要解决的问题

元素自适应问题

页面布局的实现 元素在各种屏幕上正常展示

文字rem问题

文字也采用rem的单位主要有什么问题呢?

可能会出现通过rem计算,最终呈现到页面上是 23.335px 这样的奇葩的字体大小,可能还会因此出现锯齿、模糊不清等问题; 对于大屏希望一行显示的文字多一些,小屏显示的少一些,而不是一视同仁的全部显示同样多的文字。这样在大屏下显得文字特别大。

个人建议 根据视觉要求 使用media 设置

高清图问题

1.使用 srcset 标签

<img src="http://g.ald.alicdn.com/bao/uploaded/i1/TB1d6QqGpXXXXbKXXXXXXXXXXXX_!!0-item_pic.jpg_160x160q90.jpg" 
srcset="http://img01.taobaocdn.com/imgextra/i1/803091114/TB2XhAPaVXXXXXmXXXXXXXXXXXX_!!803091114.jpg 2x, http://gtms04.alicdn.com/tps/i4/TB1wDjWGXXXXXbtXVXX6Cwu2XXX-398-510.jpg_q75.jpg 3x">

详细介绍: www.w3cplus.com/responsive/… 2、使用js自带的 Image 异步加载图片

<img id="img" data-src1x="xxx@1x.jpg" data-src2x="xxx@2x.jpg" data-src3x="xxx@3x.jpg"/>
var dpr = window.devicePixelRatio;
  if(dpr > 3){
    dpr = 3;
  };

  var imgSrc = $('#img').data('src'+dpr+'x');
  var img = new Image();
  img.src = imgSrc;
  img.onload = function(imgObj){
    $('#img').remove().prepend(imgObj);//替换img对象
  };

对于背景图片高清解决方案
  1. 使用 media query 来处理
/* 普通显示屏(设备像素比例小于等于1)使用1倍的图 */
 .css{
     background-image: url(img_1x.png);
 }

 /* 高清显示屏(设备像素比例大于等于2)使用2倍图  */
 @media only screen and (-webkit-min-device-pixel-ratio:2){
     .css{
         background-image: url(img_2x.png);
     }
 }

 /* 高清显示屏(设备像素比例大于等于3)使用3倍图  */
 @media only screen and (-webkit-min-device-pixel-ratio:3){
     .css{
         background-image: url(img_3x.png);
     }
 }

2.使用 image-set 来处理(有兼容问题)

.css {
   background-image: url(1x.png); /*不支持image-set的情况下显示*/
   background: -webkit-image-set(
           url(1x.png) 1x,/* 支持image-set的浏览器的[普通屏幕]下 */
           url(2x.png) 2x,/* 支持image-set的浏览器的[2倍Retina屏幕] */
           url(3x.png) 3x/* 支持image-set的浏览器的[3倍Retina屏幕] */
   );
 }

常见的一些兼容性处理

canvas无法使用rem单位的解决方案

我们在使用canvas时需要设置画布的大小,即设置canvas标签的width,height属性。

<canvas width="200px" height="200px"></canvas>

在移动端,画布的大小要根据屏幕的大小进行适配,我们一般采用rem结合媒体查询的方式。使用canvas时就遇到遇到一些问题:

canvas的width属性不支持rem单位(如果使用样式当然支持rem,但注意canvas的width属性与style中的width是有区别的),如下

<canvas width="2.5rem" height="2.5rem"></canvas>

translate方法传参是坐标位置,不带单位,如ctx.translate(10,10);

适配屏幕是必须的,但如何解决?用最原始的百分比布局就可以:

//获取屏幕的宽度
var  clientWidth = document.documentElement.clientWidth;
//根据设计图中的canvas画布的占比进行设置
var canvasWidth = Math.floor(clientWidth*200/720);
canvas.setAttribute('width',canvasWidth+'px');
canvas.setAttribute('height',canvasWidth+'px');
//translate方法也可以直接传入像素点坐标

方法二:

<div style="height: 100%;width: 100%;margin: 0;padding: 0;">
<canvas id="myCanvas" style=" height: 100%;width: 100%;margin: 0;padding: 0;display: block;"></canvas>
</div>

ios端微信h5页面上下滑动时卡顿、页面缺失

问题详情描述:在ios端,上下滑动页面时,如果页面高度超出了一屏,就会出现明显的卡顿,页面有部分内容显示不全的情况

解决办法:只需要在公共样式加入下面这行代码

body {
-webkit-overflow-scrolling: touch;
overflow-scrolling: touch;
}

拓展知识: -webkit-overflow-scrolling:touch是什么?

-webkit-overflow-scrolling 属性控制元素在移动设备上是否使用滚动回弹效果.

auto: 使用普通滚动, 当手指从触摸屏上移开,滚动会立即停止。

touch: 使用具有回弹效果的滚动, 当手指从触摸屏上移开,内容会继续保持一段时间的滚动效果。继续滚动的速度和持续的时间和滚动手势的强烈程度成正比。同时也会创建一个新的堆栈上下文。

有关Input输入框的问题

1、input 的placeholder属性会使文本位置偏上

  line-height: (和input框的高度一样高)---pc端解决方法
  line-height:normal ---移动端解决方法

2、input type=number之后,pc端出现上下箭头

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none !important;
  margin: 0;
}

3、IOS input的placeholder偏上

解决办法:使input的字体大小大于等于 placeholder的字体大小

  input {
    background-color: #f4f4f4;
    font-size: 0.14rem;
    color: #7f7f7f;
    }
    ::-webkit-input-placeholder { /* WebKit, Blink, Edge */
        font-size:0.14rem;  /*小于等于0.14rem即可*/
        color: #b2b2b2;
    }

4、ios 设置input 按钮样式会被默认样式覆盖

解决方法:

input,
textarea {
    border: 0;
    -webkit-appearance: none;
}

IOS 经常会出现button里面的文字偏上

解决办法: 直接使用flex布局,专治各种疑难杂症(ios低版本注意加前缀-webkit-)

.btn{
      display:flex;
      flex-direction:column;/*对于button可以使用column,像label-content这种形式还是使用row吧*/
      align-items: center;
      justify-content: center;
  }

iphone及ipad下输入框默认内阴影

Element{
-webkit-appearance: none;
}

对非可点击元素如(label,span)监听click事件,部分ios版本下不会触发。

解决方案:css增加cursor:pointer就搞定了

附:

主要的概念:

一、物理像素 分辨率 css像素

物理像素:也叫做:设备像素(device pixel)。可以理解为屏幕上的点,这个是跟硬件有关系,跟Web软件语言没一毛钱关系。

分辨率: 这也是一个物理概念,其实就是指一个设备上横竖的点数。

css像素:是Web编程的概念,指的是CSS样式代码中使用的逻辑像素(或者叫虚拟像素)。在CSS规范中,长度单位可以分为绝对单位和相对单位,比如:px 是一个 相对单位 ,相对的是 物理像素(physical pixel),这也就是说到底我们平常开发中的 1px 在每个屏幕上怎么显示,完全取决于这个设备!

二、设备像素比(device pixel ratio)

简写:dpr 公式:物理像素数(硬件) / 逻辑像素数(软件),它是设备的属性,而不是一个单位。 其实,比值就是前面说的 物理像素数 除以 CSS像素数。 在javascript中,可以通过 window.devicePixelRatio 获取到当前设备的 dpr。 在css中,可以通过 -webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio 和 -webkit-max-device-pixel-ratio 进行媒体查询,对不同dpr的设备,做一些样式适配。

例: 当 dpr=2 时,表示:1个CSS像素 = 4个物理像素。因为像素点都是正方形,所以当1个CSS像素需要的物理像素增多2倍时,其实就是长和宽都增加了2倍。

一、时间戳转换iOS 安卓不兼容处理

 // 兼容安卓 iOS写法 时间格式为'2018-08-07 10:23:00';
    let arr = time.split(/[- :]/);
    let nndate = new Date(arr[0], arr[1] - 1, arr[2], arr[3], arr[4], arr[5]);
    nndate = Date.parse(nndate);
    // 不兼容 ios
    // var endDate = new Date(time);
    // var end = endDate.getTime();
    var end = nndate;

目前大部分已使用 moment.js处理

a 标签打开不下载的bug

target="_blank" rel="noopener noreferrer"