移动端开发

相关的一些资源

使用 Whistle 作为你的 Web 调试工具吧whistle官方文档whistle插件利用whistle调试移动端页面
Mars 面向亿万用户级的移动端Web解决方案
为网站添加触摸功能

调试控制台

vConsole
Eruda

浏览器适配

可参考vant官方提供的适配demo

rem方案

推荐使用以下两个工具:

  • postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem
  • lib-flexible 用于设置 rem 基准值 或者 直接在html中增加以下代码来动态改变rem的基准值
      (function (doc, win) {
          const uiWidth = 1920;
          const docEl = doc.documentElement;
          const resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
          const recalc = function () {
              let clientWidth = docEl.clientWidth;
              if (!clientWidth) {
                  return;
              }
              if (clientWidth >= uiWidth) {
                  clientWidth = uiWidth;
              }
              docEl.style.fontSize = 100 * (clientWidth / uiWidth) + 'px';
          };
          if (!doc.addEventListener) {
              return;
          }
          win.addEventListener(resizeEvt, recalc, false);
          doc.addEventListener('DOMContentLoaded', recalc, false);
          recalc();
      })(document, window);

使用PostCSS 配置(以vue-cli3为例)

const autoprefixer = require('autoprefixer');
const pxtorem = require('postcss-pxtorem');
module.exports = {
  plugins: {
    autoprefixer: {
      browsers: ['Android >= 4.0', 'iOS >= 8'],
    },
    'postcss-pxtorem': {
      rootValue: 50,
      propList: ['*', '!border*'] // 忽略border
    },
  },
};

viewport方案

设置meta头:

 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, viewport-fit=cover">

同样可以配置插件postcss-px-to-viewport

module.exports = {
  plugins: {
    autoprefixer: {},
    "postcss-px-to-viewport": {
      unitToConvert: "px", // 默认值`px`,需要转换的单位
      viewportWidth: 750,//视窗的宽度,对应的是我们设计稿的宽度
      viewportHeight: 1334, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
      unitPrecision: 3,//指定`px`转换为视窗单位值的小数位数,默认是5(很多时候无法整除)
      viewportUnit: 'vw',//指定需要转换成的视窗单位,建议使用vw
      fontViewportUnit: 'vw', //指定字体需要转换成的视窗单位,默认vw;
      selectorBlackList: ['.ignore', '.hairlines'],//指定不转换为视窗单位的类 
      minPixelValue: 1,// 小于或等于`1px`不转换为视窗单位
      mediaQuery: false,// 允许在媒体查询中转换`px`,默认false
      exclude:[/node_modules/], //如果是regexp, 忽略全部匹配文件;如果是数组array, 忽略指定文件.
      landscape: false, 
      landscapeUnit:'vw',// (String) 横屏时使用的单位
      landscapeWidth:750,// (Number) 横屏时使用的视口宽度
    }
  }
}

viewport固定布局方案

<!DOCTYPE html>
<html>
    <meta charset="utf-8"></meta>
    <meta name="viewport" content="" id="viewMeta">
    <head>
        <title>test</title>
    </head>
    <body>
        <div id="contentBox">
        </div>
    </body>
    <script type="text/javascript">
            (function (doc, win) {
                const resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
                const meta = document.getElementById('viewMeta');
                const dpr = window.devicePixelRatio;
                const recalc = function () {
                    meta.setAttribute('content', 'initial-scale=' + 1 / dpr + ', maximum-scale=' + 1 / dpr + ', minimum-scale=' + 1 / dpr + ', user-scalable=no');
                };
                if (!doc.addEventListener) {
                    return;
                }
                win.addEventListener(resizeEvt, recalc, false);
                doc.addEventListener('DOMContentLoaded', recalc, false);
                recalc();
            })(document, window);
    
    </script>
</html>

按钮在键盘弹起时无响应

touch事件:touchstart->touchmove-> touchend 或者 touchstart->touchend->click

.only-input-body(:class="{required: required}")
    Input(v-model="value", :data="data", @updateErrorMessage="handleUpdateErrorMessage")
    // 兼容使用touchstart、click
    .btn(@touchstart.prevent="handleClickConfirm", @click.prevent="handleClickConfirm", :class="{disabled: disabled}")
         img(src="./submit.png")

文本框或输入框在滚动较长距离回滚后文字被隐藏

我的原因是祖先元素中使用的定位,同时多次使用vant组件库中的弹层,猜测组件库中多次操作遮罩层导致页面渲染问题
解决方法:用其他方式实现定位

定位元素错位

当使用了position:fixed 的元素,如果其祖先元素存在 transform 值不为 none ,那么该元素将相对于设定了 transform 的祖先元素进行定位。

为什么会出现种情况:

  • 任何非 transform 为 none 值都会导致一个堆叠上下文(Stacking Context)和包含块(Containing Block)的创建。
  • 由于堆叠上下文的创建,该元素会影响其子元素的固定定位。设置了 position:fixed 的子元素将不会基于 viewport 定位,而是基于这个父元素。

解决方案:

  • 设置 transform 为 none
  • 把使用position:fixed 的元素放置在 transform 不为 none 的外面

ios下页面滚动较长距离后再回滚某些元素被隐藏,点击后能重新展现

原因是当前元素增加了overflow:hidden

解决ios下input上边框阴影

input           
    outline: none
    -webkit-appearance: none /*去除系统默认的样式*/
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0) /* 点击高亮的颜色*/          

解决ios下滚动区域外内容无法显示问题

-webkit-backface-visibility: hidden
-webkit-transform: translate3d(0,0,0)
-webkit-overflow-scrolling: touch

-webkit-overflow-scrolling 页面锁死

在移动端上用overflow-y:scorll属性的时候,会发现滚动的效果很很生硬,很慢,这时候可以使用-webkit-overflow-scrolling:touch这个属性,让滚动条产生滚动回弹的效果,就像ios原生的滚动条一样流畅。

且这个属性会有很多坑:

  • 在safari上,使用了-webkit-overflow-scrolling:touch之后,页面偶尔会卡住不动。
  • 在safari上,点击其他区域,再在滚动区域滑动,滚动条无法滚动的bug。
  • 通过动态添加内容撑开容器,结果根本不能滑动的bug。
  • 滚动中 scrollTop 属性不会变化
  • 手势可穿过其他元素触发元素滚动
  • 滚动时暂停其他 transition

解决方案:在webkit-overflow-scrolling:touch属性的下一层子元素上,将height加1%或1px。从而主动触发scrollbar。

<div id="app" style="-webkit-overflow-scrolling: touch;">
    <div style="height:calc(100%+1px)"></div>
</div>
<!--- 或 --->
<div id="app" style="-webkit-overflow-scrolling: touch;">
    <div style="min-height:101%"></div>
</div>

公众号ios不刷新页面问题

    let isPageHide = false;
    window.addEventListener('pageshow', function () {
        if (isPageHide) {
            window.location.reload();
        }
    });
    window.addEventListener('pagehide', function () {
        isPageHide = true;
    });

Web App Icon与启动图片

iOS允许网站开发者像NativeApp一样在iOS设备的主屏幕为其网站添加一个启动Icon,这个代表着网站的Icon在苹果官方开发者文档里被称为“Web Clip”,它的作用类似于桌面浏览器的书签,用户通过点击Icon能直接快速打开这个url的网站。

实践1
实践2

一像素问题

(border-1px)[https://github.com/AlloyTeam/Mars/blob/master/solutions/border-1px.md]

border-image方案

.border-image-1px
    border-width: 1px 0px
    border-image: url("border.png") 2 0 stretch
    // border.png也可以直接使用的base64替代

CSS3 transform 方案

[class*='van-hairline']::after
    position: absolute
    box-sizing: border-box
    content: ' '
    pointer-events: none
    top: -50%
    right: -50%
    bottom: -50%
    left: -50%
    border: 0 solid #ebedf0
    transform: scale(0.5)
.van-hairline--top-bottom::after
    border-width: 1px 0

消除 transition 闪屏

-webkit-transform-style: preserve-3d;
/*设置内嵌的元素在 3D 空间如何呈现:保留 3D*/

/*或*/

-webkit-backface-visibility: hidden;
/*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/

伪类 :active 生效

要CSS伪类 :active 生效,只需要给 document 绑定 touchstart 或 touchend 事件

<style>
a {
  color: #000;
}
a:active {
  color: #fff;
}
</style>
<a herf=foo >bar</a>
<script>
  document.addEventListener('touchstart',function(){},false);
</script>

消除 IE10 里面的那个叉号

input:-ms-clear{display:none;}

iOS 与 OS X 端字体横竖屏会出现字体加粗不一致等

iOS 浏览器横屏时会重置字体大小,设置 text-size-adjust 为 none 可以解决 iOS 上的问题,但桌面版 Safari 的字体缩放功能会失效,因此最佳方案是将 text-size-adjust 为 100%

text-size-adjust: 100%;

meta 头配置

<!-- 不让 Android 手机识别邮箱 -->
<meta content="email=no" name="format-detection" />
<!-- 禁止 iOS 识别长串数字为电话 -->
<meta content="telephone=no" name="format-detection" />

禁止 iOS 弹出各种操作窗口

touch-callout:none

禁止用户选中文字

user-select:none

部分机型存在type为search的input,自带close按钮样式

inpu[type=search]::-webkit-search-cancel-button
      display: none; 
posted @ 2020-08-28 11:20  fanlinqiang  阅读(247)  评论(0)    收藏  举报