常见的移动端H5页面开发遇到的坑和解决办法-阿里云开发者社区

开发者社区> 开发与运维> 正文

常见的移动端H5页面开发遇到的坑和解决办法

简介: 问题一:用同等比例的图片在PC机上很清楚,但是手机上很模糊,原因是什么呢? 经研究发现是devicePixelRatio作怪,因为手机分辨率太小,如果按照分辨率来显示网页字会非常小,所以苹果就把iPhone 4的960640分辨率在网页里只显示了480320,这样devicePixelRatio=2;现在android比较乱,有1.

问题一:用同等比例的图片在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中的viewport;有些手机站有如下声明:

<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">

设置DTD的方式是XHTML的写法,假如页面运用的是h5可以不用设置DTD,直接声明

使用viewport使页面禁止缩放,通常把user-scalable设置为0来关闭用户对页面视图缩放的行为

<meta name="viewport" content="user-scalable=0" /> 

为了更好的兼容,我们使用完整的viewport设置

<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />

问题三:如何设置Web应用以全屏模式运行

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

<meta name="apple-mobile-web-app-capable" content="yes"> //content设置为yesWeb应用会以全屏模式运行,反之则不会;content的默认值是no,表示正常显示,可以通过只读属性window.navigator.standalone来确定网页是否以全屏模式显示

问题四:如何启动或禁用自动识别页面中的电话号码

html5提供了自动调用拨号的标签,只要在a标签的href中添加tel:就可以了

<a href="tel:10010">10010</a>

format-detection可以启动或禁用自动识别页面中的电话号码;语法:

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

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

用input search做模糊搜索的时候,在键盘里输入关键词,会通过ajax后台查询然后返回数据,然后再对返回的数据进行关键词标红;用input监听键盘keyup事件,在安卓手机浏览器中是可以的,但是在ios手机浏览器中变红很慢,用输入法输入之后,并未立刻执行相应的keyup事件,只有删除之后才能响应;解决办法是可以用html5的oninput事件去代替keyup,通过如下代码达到类似keyup的效果

<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>

问题六:h5网站input设置为type=number的问题

h5网页input的type设置为number一般会产生三个问题:一是maxlength属性不好用,另外一个是form提交的时候默认取整,三是部分安卓手机出现样式问题

问题一解决,我目前用的是js

<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>

问题二是因为form提交默认做了表单验证,step默认是1,要设置step属性,假如保留2位小数,写法如下:

<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之间

问题三去除input中这些默认样式:

input[type=number] {
    -moz-appearance:textfield;
}
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{
    -webkit-appearance: none;
    margin: 0;
}

去除input默认样式的方法:

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

问题七:IOS键盘字母输入,默认首字母大写的解决方案

设置如下属性

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

问题八:select 下拉选择设置右对齐实现

设置如下属性

select option {
    direction: rtl;
}

问题九:移动端click事件延迟的问题

移动端的点击事件都会有300ms延迟,是因为浏览器在等待你是否执行双击,但此延迟导致用户体验不好,解决这个问题,我们的方案如下:

1.尽量都使用touch事件来替换click事件,例如用touchend事件(推荐)

2.用preventDefault阻止a标签的click

3.用script标签引入fastclick库去除延迟,实验证明fastclick比tap要快

4.zepto的touch模块,tap事件也是可以解决在click的延迟问题

5.延迟一定的时间(300ms+)来处理事件(不推荐)

6.以上一般都能解决,实在不行就换成click事件

7.触摸事件的响应顺序为touchstart-->touchmove-->touchend-->click,也可以通过绑定ontouchstart事件,加快对事件的响应,解决300ms延迟问题

8.若移动设备兼容性正常的话(IE/Firefox/Safari(IOS 9.3)及以上)只需加上下面meta标签即可把viewport设置成设备的实际像素,就不会有300ms的延迟

<meta name="viewport" content="width=device-width">

click事件的延迟会导致移动端点透问题

案例如下:

<div id="haorooms">事件测试</div>
<a href="#">www.xxx.com</a>

div是绝对定位的蒙层且z-index高于a,我们给div绑定tap事件:

$('#haorooms').on('tap',function(){
    $('#haorooms').hide();
});

我们点击蒙层时div正常消失,但是当我们在a标签上点击蒙层时,发现a链接被触发,这就是所谓的点透事件

原因:touchstart早于touchend早于click,即click的触发是有300ms左右延迟的,也就是说tap触发之后蒙层隐藏click没有触发,300ms之后由于蒙层消失click触发到了下面的a链接上;解决方案同上面的click事件延迟

问题十:关于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%;

问题十一:iOS系统中,中文输入法输入英文时,字母之间可能会出现一个六分之一空格的问题

可以通过正则去掉

this.value = this.value.replace(/\u2006/g, '');

问题十二:移动端HTML5 audio autoplay失效问题

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

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

问题十三:移动端样式兼容处理

当今的手机端,屏幕分辨率各有不同,为了让页面可以兼容各款手机,解决方案如下:

1.设置meta标签viewport属性,使其无视设备的真实分辨率,直接通过dpi在物理尺寸和浏览器之间重设分辨率,从而达到能有统一的分辨率的效果,并且禁止掉用户缩放

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

2.使用rem进行屏幕适配,设置好root元素的font-size大小,然后在开发的时候所有与像素有关的布局统一换成rem单位;针对不同的手机使用媒体查询对root元素font-size进行调整

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

针对此种情况只需对不触发click事件的元素添加一行css代码即可

cursor: pointer;

问题十五: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); //可以触发硬件加速,从而让浏览器在渲染动画时从CPU转向GPU

目前像Chrome/Filefox/Safari/IE9+以及最新版本Opera都支持硬件加速,当检测到某个DOM元素应用了某些CSS规则时就会自动开启,从而解决页面闪白,保证动画流畅

问题十六:浮动子元素撑开父元素盒子高度

解决方法如下:

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

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

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

BFC产生的条件:

1.html根元素

2.float的值不为none

3.display的值为inline-block/table-cell/table-caption

4.position的值为absolute或fix

5.overflow的值不为visible

BFC约束规则:

1.生成BFC元素的子元素会一个接一个的放置;垂直方向上他们的起点是一个包含块的顶部,俩个相邻子元素之间垂直距离取决于元素margin特性,在BFC中相邻的块级元素外边距会折叠

2.生成BFC元素的子元素中每个子元素的外边距和包含块的左边界相接触(对于从右到左的格式化,右外边距和右边界相接触),除非这个子元素也创建一个新的BFC(如它自身也是一个浮动元素)

3.BFC的区域不会与float的元素区域重叠

4.计算BFC高度时浮动元素也参与计算

5.BFC就是页面上一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然

我们在写css常见的一些问题都可以由上面两条推出,例如:

1.Block元素与父元素同宽,所以Block元素竖直方向上垂直排列。

2.竖直方向上有的Block元素margin会重叠,水平方向不会。

3.浮动元素会尽量接近左上方或右上方。

4.为父元素设置overflow:hidden或浮动父元素,则父元素会包含其浮动的子元素。

BFC有很多实际的用处,例如防止相邻block的竖直margin重叠(塌陷)

问题十六:往返缓存问题

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

window.onunload = function(){};

感悟:挑战和机遇永远是最亲的兄弟,只看你怎么去看待他们

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章