手机端Web开发中遇到的那些问题

retina 图片兼容

这个 feature 应该不仅仅只关心 手机端, 而且还包括PC, 因为苹果不仅仅在手机端 (从 iphone4 开始), 而且在,
MAC 上也使用了 retina. 首先, retina 的意思就是, dpr(device-pixel-ratio)是普通屏幕的两倍.
对比于 CSS 来说就是, 原来在 css 中设置的是 1px , 在实际的屏幕显示时, 也是 1px. 但是, 在 retina 下,
css 的 1px 就是实际屏幕的 2px.

这样的结果就是:

有同学会想, 会啥会这样呢? 命名看起来大小一样的, 为什么图片变模糊了?这实际上是位图的特性. 比如一个 jpg 文件, 大小是 200×300. 那么他的实际屏幕像素就是 200px × 300px. 放在 dpr=1 的屏幕中, 大小设置为:


  1. width: 200px; 
  2.  
  3. height:300px;  

这样, 当然可以正常显示. 但在 retina 中, 每个 css px 等于 2 倍的 px. 这样,
原来正常显示的图片就被放大了一倍. 原来图片上每个点,可以正好的放在 dpr=1 的屏幕中, 而在 dpr=2 时, 每个点都被拆分了,
所以就有锯齿造成模糊的现象.

而解决办法也有很多.

使用 media query

这种方法适用于背景图的添加. 使用到的是 css3 提供的 device-pixel-ratio query 来进行执行. 简单的demo就是:


  1. #myimage { 
  2.     width: 400px; 
  3.     height: 300px; 
  4.     background: url(lo-res.jpg) 0 0 no-repeat; 
  5.  
  6. // 这里主要针对的是 Android 的一些设备 
  7. @media 
  8. screen and (-webkit-min-device-pixel-ratio: 1.5), 
  9. screen and (min--moz-device-pixel-ratio: 1.5), 
  10. screen and (-o-min-device-pixel-ratio: 3/2), 
  11. screen and (min-device-pixel-ratio: 1.5) { 
  12.     #myimage { 
  13.         background-image: url(hi-res.jpg); 
  14.     } 
  15.  
  16. // 如果你想针对苹果的, 则可以直接使用: 
  17. @media only screen and (-webkit-device-pixel-ratio: 2), 
  18.        only screen and (-moz-device-pixel-ratio: 2), 
  19.        only screen and (-o-device-pixel-ratio: 2/1), 
  20.        only screen and (device-pixel-ratio: 2) { 
  21.         #myimage { 
  22.         background-image: url(hi-res.jpg); 
  23.     } 
  24. }  

但这样成本很大, 而且每次都需要准备两份, 做一些价值特别低的工作.

使用 js 判断

除了上面写冗余的 css 代码外, 还可以使用 js 进行判断. 然后,替换 data-src 里面的内容进行懒加载.


  1. if (window.devicePixelRatio > 1) { 
  2.         var images = $("img"); 
  3.         images.each(function(i) { 
  4.             var x1 = $(this).attr('data-src'); 
  5.             $(this).attr('src',x1); 
  6.         }); 
  7.     }  

而且,该属性的支持度挺高的, 基本上所有的手机端和PC 都支持, 除了 IE8.

使用矢量图

在 web 中使用矢量图的方式有很多. 比如, SVG, Fonts. 这两个, 应该是最适合的, 不过, 在画图时,
大多都是位图的形式, 所以, 需要转换为 SVG 和 fonts 来说, 难度有点大. 针对一些小的 logo 和 icon 来说,
还是没太大的问题的. 并且, 上述的两种方式所占用的空间大小也是很小的.

手机基本情况

现在手机的问题不在 js 脚本, 而在页面渲染. 因为, 手机的屏幕显示全是通过 CPU 进行处理. 而没有像 PC 端一样有独立的显卡专门来对图像进行绘制.

手机上的键盘

一般遇到需要输入的元素标签, 比如, input 当获取焦点时, 都会触发键盘的弹出. 但, 对于 ios 和安卓, 这两者的键盘弹出的处理方式不一样.

ios 的键盘

键盘的渲染有两种方式:

  • 如果 input 已经在键盘的上方, 则只是会将控件向上推一点, 推导键盘的上方.
  • 如果 input 在键盘的下方,键盘会覆盖该控件, 并将整个页面向上推, 直到控件推到键盘上方为止.

另外, 当在 ios7 一下时, 如果有元素是 fixed 属性. 那么,此时打开 键盘时, fixed 有可能会当做 absolute 进行渲染. 所以, 这真是个问题.

android 的键盘

同样,也有两种情况.

  • 第一种没问题
  • 第二种, 当 input 在键盘的下方, 会将整个 document 的高度增加, 直到控件高度超过键盘高度为止.

对于 android 将整个 document 向上推的情况, 对于绝对定位和 fixed 属性定位来说. 会存在一定的问题. 增加
document 并未增高 viewport 的位置, 所以, 如果使用 fixed 可能会出现, 元素跑到键盘下面. 但,
由于键盘是在整个浏览器上方的, 所以, 你也不可能覆盖掉键盘. 一般的解决办法就是, 监听输入的 focus 事件, 来动态 设置fixed
的位置.(不过好复杂).

软盘类型

针对于不同的输入,键盘上显示的类型实际上是不一样的, 一般兼容性比较好的是:数字/手机号. 可以设置为:


  1. input[type=tel] 
  2.  
  3. input[type=number]  

软盘人工弹起

当用户没有触发 input 的 focus 事件. 而是开发者人工触发的, 这里就有两种不同的情况.

IOS

ios6 以前, 当控件触发了 focus 事件, 但, focus 不是用户触发的, 那么键盘是不会弹起的.

在 ios6 以后, 可以手动添加一个 autofocus 属性即可.

Android

只要不是用户触发的,都不能弹起.

键盘的收起

键盘的收起直接触发 js 的 blur 事件即可.

页面滚动

设计到页面滚动有两个事件, 一个是 scroll, 一个是 touchmove.

手机端为了解决性能问题, 当页面进行滚动时, js 进行的动态渲染是无效的, 即, 使用 js 改变页面上元素的位置,是无效的.
知道页面滚动结束才行. 这种效果主要体现在 scroll 事件触发的机制上. 在 ios8 以下, 当页面滚动时, js 的渲染被暂停了.
而,对于 Andriod 4.0 以上来说, scroll 触发都是连续滚动的.

如果你想设置局部滚动, 可以添加 -webkit-overflow-scrolling: touch css 属性.

flex 问题

由于历史原因, 想在 web 上实现 flex 的效果. 则需要注意他的兼容性, 因为 flex 有三个版本, 而且三个版本的支持性都不一样.分别是:

  • display: box
  • display: flexbox
  • display: flex

由于 Android 使用的是 Webkit 开源内核, 我们需要给 flex 加上 webkit 前缀, 来兼容 低版本 Android.


  1. display: -webkit-box; 
  2. display: -moz-box; 
  3. display: -ms-flexbox; 
  4. display: -webkit-flex; 
  5. display: flex;  

目前的兼容性是:

  • old 使用的是 display: box;
  • tweener 使用的是 display: flexbox;
  • new 使用的是 display: flex;

fixed 问题

在 mobile 里面使用 fixed 是一个比较复杂的问题. 因为,在输入时, 往往还会设计到键盘的弹出, 鉴于 ios 和 android 的不同效果. fixed 有可能在键盘弹出时, 出现错位的现象. 例如:

具体参考: fixed. 在 ios5 以前是不支持 fixed, android 在 4.x 之后, fixed 基本上才可用.

touch 事件解析

300ms click 时延

click 时延算是, web 手机开发的一个坑吧. 因为厂商在设计手机端时, 主要, 考虑到缩放的事.

即:

当第一次点击时, 并不会触发 click 时间, 浏览器会等待 300ms 时延, 并判断你在 300ms 内,有没有再次点击, 如果有,
则会触发 zoom in 的效果。 后来, 300ms 时延被取消了, 同时, 长按选中文本也取消了. 后来觉得不行, 又加上了. 在
Chrome 32+, IE/FF 都是 Ok的. 最近在 IOS 9.3 中也得到了修复.

不过前期是, 你需要在 head 标签里面加上.


  1. // 告诉浏览器取消双击放大的效果 
  2.  
  3. <meta name="viewport" content="width=device-width">  

或者给特定的 tag 加上特定的 css 属性


  1. html { 
  2.  
  3.     touch-action: manipulation; 
  4.  
  5. }  

不过 FF 不支持.

click 点透

这个 feature 应该算是比较经典了. 当一个罩层覆盖在一个 a 标签上。


  1. <div id="model"></div> 
  2.  
  3. <a href="www.villainhr.com">www.villainhr.com</a>  

此时, model 是覆盖在 a 标签上的. 当点击罩层, 罩层消失. (罩层绑定的是 tap 事件) 由于, click 事件有 300ms 时延, 所以, 此时 a 标签的跳转效果会触发. 解决办法是:

  • 设置罩层延时消失效果. 延时时间设置为 300ms+ 即可.
  • 在 touchend 里面执行 preventDefault()
  • 使用插件禁止掉 click 事件, 转而使用模拟的.

触摸事件详解

在手机上是没有关于鼠标的相关操作的, 比如 hover, mouseover, mousenter等等. 只有, 相关的 touch 事件.

  • touchstart 当第一根手指触摸到屏幕时, 触发.
  • touchmove 当某一个手指在屏幕上移动时, 触发.
  • touchend 当手指从屏幕上移开时, 触发.
  • touchcancel 当手指触控被打断时触发. 具体有一下几种.

。其他事件的发生打断了 touch 事件. 比如, js 操作强制跳转

。当浏览器的 UI 覆盖到当前的 web 上

。触摸的手指数超过了浏览器的支持数量. 如果发生, 那么第一根触摸的手指会被取消

// 暂不支持下列两个事件

  • touchenter 当手指进入指定元素
  • touchleave 当手指移出指定元素

因为在触发 touch 事件时, 不仅仅只是相关的 touch 事件会触发, 还会触发相关的 mouse 和 click 事件. 所以,
如果 mouse 和 click 事件有影响时, 则需要显示的使用 event.preventDefault() 取消掉后面的触发机制.

在每个 touch 事件里面, 还会返回挂载到 event 上的属性, 常用的有:

  • touches: 当前屏幕上的属性
  • targetTouches: 在指定 DOM 元素上的属性
  • changedTouches: 返回触发时间的相关手指数. 比如, touchmove 事件中, 返回正在移动的手指. 在 touchend 事件中, 返回移除的手指.

并且每一个 touch 上面都会附带相关的属性.

  • identifier: 每一个手指独一无二的 ID
  • target: 返回一开始触发 touch 事件的 DOM 元素
  • screenX/Y: 返回相对于整个手机屏幕而言的位置.
  • pageX/Y: 返回相对于整个页面的位置, 包括 scroll 的距离.
  • clientX/Y: 返回相对于浏览器 viewport 的位置. 不包含 scroll 的距离.
  • radiusX/Y: 返回手势椭圆的长轴和短轴的大小. 目前来说, 还不支持. 和 screenX/Y 有点类似.

touchmove 的坑

移动而不滚动

当触发 touchmove 时. 如果,不加限制的话, 往往会触发 scroll 的效果. 为了消除这样的问题, 只需要将默认行为禁掉就 ok.


  1. document.body.addEventListener('touchmove', function(event) { 
  2.   event.preventDefault(); 
  3. }, false);  

不要将 touchmove 来用作渲染触发

因为, touchmove 的机制是浏览器自身来决定的. 他触发的次数是很有限的. 所以, 我们一般只是利用 touchmove 来获得数据, 而渲染则需要使用 requestAnimationFrame .


  1. var touches = [] 
  2. canvas.addEventListener('touchmove', function(event) { 
  3.   touches = event.touches; 
  4. }, false); 
  5.  
  6. // Setup a 60fps timer 
  7. timer = setInterval(function() { 
  8.   renderTouches(touches); 
  9. }, 15);  

媒体查询

媒体查询机制在 css2 里面就已经提出来. 比如, 针对打印机的:


  1. <link rel="stylesheet" media="print" href="printer.css"> 

不过, 在 css3 中, 媒体查询的机制得到了补充. 并且除了 IE8 以外, 其他浏览器或者说, 手机端都是支持的. 他主要的用途还是区分 手机端,PC端, 屏幕的大小等.

屏幕大小

先看个 demo:


  1. <link rel="stylesheet"  media="only screen and (min-width: 641px) and (max-width: 800px)" href="ipad.css">  

设置当屏幕的大小为 [641,800]之间时, 才加载 ipad.css. 如果, 不符合, 浏览器会默认忽略这个 tag. 其中 only 这个 flag 是非常重要的. 他主要作用就是告诉浏览器不符合则忽略的规则.

通过, 屏幕的大小来判断 mobile , pad , PC 是比较有用的.

meta 标签

meta 主要用来设置网页的源信息, 比如, 缩放, 宽度等等. 最常用的就是手机端上的


  1. <meta content=" 
  2. width=device-width;  // 网页初始宽度和设备宽度一致 
  3. initial-scale=1.0;  // 初始放大效果 
  4. maximum-scale=1.0;  // 最大放大效果 
  5. user-scalable=no"   // 防止用户缩放 
  6. name="viewport" />  
  7.  
  8. <meta content="yes" name="apple-mobile-web-app-capable" />  //允许全屏模式浏览 
  9. <meta content="telephone=no" name="format-detection" /> //忽略将屏幕中的数字识别为电话号码;  

这里只是整理了一些皮毛, 有兴趣的同学,可以参考另外两篇文章:

后面如果遇到些比较坑的问题, 会及时更新的。

作者:jimmy_thr

来源:51CTO

时间: 2025-01-21 19:38:17

手机端Web开发中遇到的那些问题的相关文章

使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OSS(https://www.aliyun.com/product/oss) 4.HTTPS(http://baike.baidu.com/view/14121.htm) 阅读目录结构 引: 一.准备工作 二.整体功能结构 三.具体实现步骤 四.关键点和问题处理 五.延伸与扩展 六.总结与思考 引:

WEB设计技巧:Web开发中经常使用的网站和Web App

文章描述:Web用户体验师Jake Rocheleau撰写了一篇文章分享他在Web开发中经常使用的网站和Web App,其中包含各类字体库.代码库.插件库.配色方案和测试工具.他同时指出,Web开发环境将慢慢转向云端. Web用户体验师Jake Rocheleau撰写了一篇文章分享他在Web开发中经常使用的网站和Web App,其中包含各类字体库.代码库.插件库.配色方案和测试工具.他同时指出,Web开发环境将慢慢转向云端. CodeVisually是一个开源项目.在它的分类目录下有各种插件.

Ajax在进行web开发中的安全性分析

在进行web开发中ajax的安全性如何呢?现在浏览器允许用户提高他们的安全等级,关闭 JavaScript 技术,禁用浏览器中的任何选项.在这种情况下,代码无论如何都不会工作.此时必须适当地处理问题,这需要单独的一篇文章来讨论,要放到以后了(这个系列够长了吧?不用担心,读完之前也许您就掌握了).现在要编写一段健壮但不够完美的代码,对于掌握 Ajax 来说就很好了.以后我们还将讨论更多的细节. Ajax 世界中的请求/响应 现在我们介绍了 Ajax,对XMLHttpRequest对象以及如何创建它

WEB开发中Spring AOP实际应用一例

web   在WEB开发中,用户对网页的访问权限检查是一个重要的环节.以STRUST为例,我们需要在Action的excute方法中编写相关的代码(一般是调用基类的函数),也很显然,在每个Action中这是一种重复劳动. 如果我们在excute运行之前,能够自动去调用基类的权限检查函数,这无疑是个好的解决办法.AOP就为我们提供了这样一种解决方法. 下面以一个简化的实例介绍实现的办法. 首先我们做一个接口: public interface CheckInterface {  public ab

Asp.net,IBatis For .Net,DAOFactory在Web开发中的数据表示

asp.net|web|数据 摘要: 本文谈论的结合Asp.net,IBatis,DAOFactory谈Web开发中的数据表示,展现在ASP.Net开发中各层怎么来组织数据. IBatis For .Net是一个功能强大实用的SQL Map工具,不是ORM工具.它是将SQL语句映射成.NET对象,同时将这个.Net对象与ASP.NET页面中的数据(ASP.NET中Page DataSource我称之为FormBean吧(与J2EE中的FormBean不是同一个概念))结合起来,这样就可以达到这个

Web开发中如何管理ipad屏幕的方向变化

Web开发中,我们会遇到在手机垂直或水平视角时展示不同状态的情况.下面我来总结一下检测移动设备方向变化的一些方法. 1 使用javascript 直接看代码: <script type="text/javascript"> window.onorientationchange = function () { if ( orientation == 0 ) { alert ('Portrait模式, Home键在下边'); } else if ( orientation ==

WEB开发中图片格式的合理选择

从某种程度上说,判断一个网页设计师是否优秀,可以从其在WEB开发(或网页设计)中是否合理的采用各种图片格式得出结论.事实上,或许所有人都知道图片存在GIF,JPG和PNG等格式,但并非所有人都知道它们之间的具体区别和使用技巧. 接下来将给大家介绍:WEB开发中几种最受欢迎图片格式的前世今生以及如何正确的使用它们. 1.JPEG JPEG格式是一种大小与质量相平衡的压缩图片格式.通俗一点讲,就是:高的压缩比=低的图片质量=小的文件大小.反之,低的压缩比=高的图片质量=大的文件大小.由于JPEG文件

对Web开发中前端框架与前端类库的一些思考

  这篇文章主要介绍了对Web开发中前端框架与前端类库的一些思考,本文讲解了前端框架的理解误区.前端框架与前端类库的区别.前端MVC框架思想等内容,需要的朋友可以参考下 说起前端框架,我也是醉了.现在去面试或者和同行聊天,动不动就这个框架碉堡了,那个框架好犀利. 当然不是贬低框架,只是有一种杀鸡焉用牛刀的感觉.网站技术是为业务而存在的,除此毫无意义,框架也是一样.在技术选型和架构设计当中,脱离网站业务发展的实际,一味的追求时髦新技术,可能会适得其反,将网站发展引入崎岖小道.就好像一个日均pv只有

Web开发中的弹出对话框控件介绍

Web开发中,目前由于Jquery的大行其道,因此很多弹出对话框,都用到了Jquery技术,反而原始的弹出对话框的方式较为少用了.不过基于JQuery的方式实现对话框窗口弹出,也有很多控件可以利用,由于工作需要及业余兴趣所至,我比较了近10种的对话框控件,其中发现有一些做得很好的,除了功能强大,而且也支持多种皮肤样式,甚至有些对话框的居中都考虑到了,细节决定体验,有些真的不错. 1.原始的弹出对话框实现(弹出窗口也可以) 我们知道,以前在没有应用其他javascript库(例如各种类型的Jque