移动端H5页面开发坑点指南

资料链接 https://mp.weixin.qq.com/s/ExS2gRGY5zFXF_vh0riLSA

一、canvas在retina屏模糊

只需要将画笔根据像素比缩放即可

run(canvasEl) {
    const canvas = canvasEl;
    const ctx = canvas.getContext('2d');
    const devicePixelRatio = window.devicePixelRatio || 1;
    const backingStorePixelRatio = ctx.webkitBackingStorePixelRatio ||
    ctx.mozBackingStorePixelRatio ||
    ctx.msBackingStorePixelRatio ||
    ctx.oBackingStorePixelRatio ||
    ctx.backingStorePixelRatio || 1;

    const ratio = devicePixelRatio / backingStorePixelRatio;
    if (devicePixelRatio !== backingStorePixelRatio) {
      const oldWidth = canvas.width;
      const oldHeight = canvas.height;

      canvas.width = oldWidth * ratio;
      canvas.height = oldHeight * ratio;

      canvas.style.width = `${oldWidth}px`;
      canvas.style.height = `${oldHeight}px`;
      ctx.scale(ratio, ratio);
    }
  },

二、 用同等比例的图片在PC机上很清楚,但是手机上很模糊,原因是什么呢?

经研究发现是devicePixelRatio作怪,因为手机分辨率太小,如果按照分辨率来显示网页字会非常小,所以苹果就把iPhone 4的960640分辨率在网页里只显示了480320,这样devicePixelRatio=2;现在android比较乱,有1.5/2/3等,想让图片在手机里显示更为清晰必须使用2x的背景图来代替img标签(一般情况都是用2倍),例如一个div的宽高是100100,背景图必须得200200,然后background-size:contain;,这样显示出来的图片就比较清晰了;代码如下:

   background:url(../images/icon/all.png) no-repeat center center;
   -webkit-background-size:50px 50px;
   background-size: 50px 50px;
   display:inline-block; 
   width:100%; 
   height:50px;

三、启动或禁用自动识别页面中的电话号码;

<meta name="format-detection" content="telephone=no">

默认情况下设备会自动识别任何可能是电话号码的字符串,设置telephone=no可以禁用这项功能,设置不识别邮箱和地址也同理

四、h5网站input设置为type=number的问题

h5网页input的type设置为number一般会产生三个问题:

问题1:maxlength属性不好用

<input type="number" oninput="checkTextLength(this ,10)">
<script type="text/javascript">
    function checkTextLength(obj, length) {
        if(obj.value.length > length)  {
            obj.value = obj.value.substr(0, length);
        }
    }
</script>

问题2:form提交的时候默认取整

<input type="number" step="0.01" /> 
/** input中type=number一般会自动生成一个上下箭头,点击上箭头默认增加一个step,
点击下箭头默认会减少一个step;number中默认step是1,也就是step=0.01可以允许输入2位小数,并且
点击上下箭头分别增加0.01和减少0.01;step和min一起使用时数值必须在min和max之间 */

问题3:部分安卓手机出现样式问题

去除input默认样式的方法:

input,textarea {
    border: 0;
    -webkit-appearance: none; 
/**可同时屏蔽输入框怪异的内阴影,解决iOS下无法修改按钮样式,
测试还发现,加了此属性后,iOS下默认还是有圆角的,
不过可以用border-radius属性修改*/
}

五、select下拉选择设置问题

问题1:右对齐实现

设置如下属性

select option {
    direction: rtl;
}

问题2:禁用select默认箭头

::-ms-expand修改表单控件下拉箭头,设置隐藏并使用背景图片来修饰

select::-ms-expand { display:none; }

六、移动端HTML5 audio autoplay失效问题

由于自动播放网页中的音频或视频会给用户带来困扰或不必要的流量消耗,所以苹果系统和安卓系统通常都会禁止自动播放和使用JS的触发播放,必须由用户来触发才播放;解决方法思路:先通过用户touchstart触碰触发播放并暂停(让音频开始加载),后面用JS再操作就没问题了;解决代码:

document.addEventListener('touchstart', function () {
    document.getElementsByTagName('audio')[0].play();
    document.getElementsByTagName('audio')[0].pause();
});

七、CSS动画页面闪白,动画卡顿,图片错乱的问题

1.尽可能地使用合成属性transform和opacity来设计CSS3动画,不使用position的left和top来定位
2.开启硬件加速

-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);

八、浮动子元素撑开父元素盒子高度(BFC)

解决方法如下:

1.父元素设置为 overflow: hidden;

2.父元素设置为 display: inline-block;等

这里两种方法都是通过设置css属性将浮动元素的父元素变成BFC(块级格式化上下文)元素,使子元素高度可以撑开父元素;不过最好使用方法1,因为inline-block元素本身会自带一些宽高度撑开其本身。

九、往返缓存问题

点击浏览器的回退有时候不会自动执行js,特别是在mobilesafari中;这与往返缓存(bfcache)有关系,解决方法:

window.onunload = function(){};

十、定位的坑

在IOS下fixed定位在软键盘顶起时会失效,所以我们在开发时统一使用absolute代替

十一、audio元素和video元素在ios和andriod中播放问题

<audio src="music/bg.mp3" autoplay loop controls>你的浏览器还不支持哦</audio> //音频,写法一
<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>

到这里一般都可以播放音乐了,如果还不行很有可能是微信的限制。
如果是微信的限制,这时需要调用微信接口,

  1. 页面先引入:
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

2)然后JS写入微信事件:

document.addEventListener("WeixinJSBridgeReady", function() {
    document.getElementById('music').play();
}, false);

小结:

1.audio元素的autoplay属性在IOS及Android上无法使用,在PC端正常

2.audio元素没有设置controls时,在IOS及Android会占据空间大小,而在PC端Chrome是不会占据任何空间

Safari浏览器自动播放


document.addEventListener('touchstart', function(){   
    audio.play();
}, false);

十二、ios系统不支持动画暂停样式(animation-play-state)

H5页面一般都会有BGM,也会提供一个旋转的音乐图标供用户开启关闭音乐;我们希望当用户点击音乐按钮时图标停止旋转,再点图标顺着之前停止的位置继续跑动画;animation-play-state是最简便的方式,然而ios不支持。

目前的解决方案是:音乐图标负责跑动画,图标父级元素负责记录停止时的转动值。

十三、ios防止长按页面元素被选中

解决方案: 加入样式可禁止用户进行复制,ios和一般的安卓都可以解决

-webkit-touch-callout:none;  //系统默认菜单被禁用;可以实现页面因为长按弹出各种操作窗口
-webkit-user-select:none; //webkit浏览器  
-khtml-user-select:none; //早期浏览器 
-moz-user-select:none; //火狐 
-ms-user-select:none; //IE10 
user-select:none; 

添加完这段代码后在IOS上会有问题,这时发现input框无法正常输入内容了;造成这个原因是-webkit-user-select:none;这个属性,解决方法就是在css文件中同时设置一下input的属性,如下:

input {      
     -webkit-user-select:auto; //webkit浏览器    
}

十四、html5碰到上下拉动滚动条时卡顿/慢怎么解决

首先你可能会给页面的html和body增加了height: 100%, 然后就可能造成IOS上页面滑动的卡顿问题。
解决方案:

1.让html和body固定100%(或者100vh);

2.然后再在内部放一个height:100%的div,设置overflow-y: auto;和-webkit-overflow-scrolling: touch。

overflow-x:auto在iOS有兼容问题,解决方法:

.scroll-box {
  /* 模态框之类的div不能放在这个容器中,否则关闭模态框有时候关闭不了 */
  height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overflow-scrolling: touch;
}

十五、点击元素产生背景或边框怎么去掉

a,button,input,textarea{ 
  -webkit-tap-highlight-color: rgba(0,0,0,0); 
  -webkit-user-modify: read-write-plaintext-only; //-webkit-user-modify有个副作用,就是输入法不再能够输入多个字符 
} 
//或 
a,button,input,textarea{ 
  -webkit-tap-highlight-color: rgba(0,0,0,0); 
}

十六、浏览器后退不刷新

这种情况是以前遇到的,这里也说下;主要会发生在webview里多一点,当点击后退时页面以缓存形式出现,而不是刷新后的,很多情况下这不是你预期的效果,解决方法是用js:

// 方法1:
window.addEventListener('pageshow', () => {
  if (e.persisted || (window.performance && 
    window.performance.navigation.type == 2)) {
    location.reload()
  }
}, false);

// 方法2:
window.history.replaceState(null, '', 
    window.location.href + '?timestamp=' + new Date().getTime());

onpageshow每次页面加载都会触发,无论是从缓存中加载还是正常加载,这是他和onload的区别;persisted判断页面是否从缓存中读出

页面通过历史记录和前进后退访问时。type值为2

十七、transition清除闪屏

-webkit-transform-style: preserve-3d; //设置内嵌的元素在 3D 空间如何呈现:保留3D
-webkit-backface-visibility:hidden; //设置进行转换的元素的背面在面对用户时是否可见:隐藏
-webkit-perspective: 1000;

十八、解决active伪类失效

<body ontouchstart></body>

十九、顶部状态栏背景色

apple-mobile-web-app-capable是设置Web应用是否以全屏模式运行;语法:

<meta name="apple-mobile-web-app-capable" content="yes">
 //content设置为yes, Web应用会以全屏模式
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

说明:除非你先使用apple-mobile-web-app-capable指定全屏模式,否则这个meta标签不会起任何作用;如果content设置为default,则状态栏正常显示;如果设置为blank,则状态栏会有一个黑色的背景;如果设置为blank-translucent,则状态栏显示为黑色半透明;如果设置为default或blank,则页面显示在状态栏的下方,即状态栏占据上方部分;页面占据下方部分,二者没有遮挡对方或被遮挡;如果设置为blank-translucent,则页面会充满屏幕,其中页面顶部会被状态栏遮盖住(会覆盖页面20px高度,而iphone4和itouch4的Retina屏幕为40px);默认值是default。

ios专区

二十、IOS中对input键盘事件keyup/keydown/keypress等支持不好的问题

经查发现,IOS的输入法(不管是第三方还是自带)能检测到英文或数字的keyup,但检测不到中文的keyup,在输入中文后需要点回退键才开始搜索;解决办法是用html5的oninput事件去代替keyup,通过如下代码达到类似keyup的效果;

1.修改了input:checkbox或input:radio元素的选择中状态,checked属性发生变化
2.修改了input:text或textarea元素的值,value属性发生变化
3.修改了select元素的选中项,selectedIndex属性发生变化 统一使用input监听

<input type="text" id="testInput">
<script type="text/javascript">
    document.getElementById('testInput').addEventListener('input', function(e){
        var value = e.target.value;
 //e.target指向事件执行时鼠标所点击区域的那个元素;初学者会认为
//当前事件所绑定的元素就是鼠标所点击的那个元素,
// 这时就要看看实际绑定的元素内部有没有子元素,如果有e.target指向这个子元素,
//如果没有e.target和this都指向事件所绑定的元素
    });
</script>

二十一、IOS键盘字母输入,默认首字母大写的解决方案

设置如下属性

<input autocapitalize="off" autocorrect="off" />

input的三个属性:

  • autocomplete:默认为on,代表是否让浏览器自动记录输入的值,可以在input中加入autocomplete="off"来关闭记录,保密输入内容;
  • autocapitalize:自动大小写;
  • autocorrect:纠错

二十二、关于iOS与OS X端字体的优化(横竖屏会出现字体加粗不一致等)问题

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

-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
text-size-adjust: 100%;

二十三、某些情况下非可点击元素如(label,span)监听click事件,ios下不会触发

cursor: pointer;

二十四、ios对时间date()的支持不一样

var date =new Date("2019/10/21");

调试发现2019/10/21等同2019-10-21 00:00:00,也就是说ios默认就是从0开始计算的,我们不需要设置后面的时分秒为00:00:00

二十五、iOS(safari)标签绑定点击事件无效

iOS(safari)有时候某个标签绑定点击事件无效,加上空的onclick=""就好了,如:<a onclick=""></a>

二十六、ios中location.href跳转页面空白

在location.href外套一层setTimeout就解决了!

setTimeout(() => {
       window.location.href = 'www.juejin.im'
}, 0);

二十七、键盘弹起下落时的bug解决方法

在App.vue的created钩子里统一处理即可


created() {
    this.handleFocusOut();
    this.handleResize();
},
methods:{
    handleFocusOut() {
      /** input 焦点失焦后,ios 键盘收起,
         但没有触发 window resize,导致实际页面dom仍然被键盘顶上去--错位*/
      document.addEventListener('focusout', () => {
        document.body.scrollTop = 0;
      });
    },
    /** 监听resize事件(键盘弹起触发),
然后将 input textarea 元素滑动到可视区域,并将特定元素隐藏*/
    handleResize() {
      const clientHeight = document.documentElement.clientHeight;
      window.addEventListener('resize', () => {
        // 判断当前 active 的元素是否为 input 或 textarea
        if (
          document.activeElement.tagName === 'INPUT' ||
          document.activeElement.tagName === 'TEXTAREA'
        ) {
          setTimeout(() => {
            // 原生方法,滚动至需要显示的位置
            document.activeElement.scrollIntoView();
          }, 0);
        }

        // 解决键盘弹起后 fixed 定位元素被顶起问题
        const bodyHeight = document.documentElement.clientHeight;
        const ele = document.getElementById('fixed-bottom');
        if (ele) {
          if (clientHeight > bodyHeight) {
            ele.style.display = 'none';
          } else {
            ele.style.display = 'block';
          }
        }
      });
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容