文档章节

关于移动端前端开发和PC端前端开发的一点总结

武文海
 武文海
发布于 2014/10/28 12:39
字数 2687
阅读 9827
收藏 17

首先就是操作兼容性和个移动版浏览器的兼容性:传统设备上用户利用鼠标(包括触摸版)和键盘来操作网页,放大图片、拖拽元素、进行页面滚动等等。一些常见的鼠标和键盘事件诸如mouseover、mouseout、mousemove、click、foucs、blur等为我们提供了很好的页面交互操作,具体可以参考W3school

   然而,开发支持触摸屏的网页与传统意义上的网页有很大的不同。就拿鼠标hover事件来说,例如页面上有一个表格,当鼠标指向表格的 title时你希望在附近的某个地方显示一个浮动的tooltip。当然,你希望这个tooltip能更加引起浏览者的注意,因此你自定义了一个DIV元 素并且通过JavaScript让它动态显示或隐藏。这个程序很简单,并且在普通设备的多个不同版本的浏览器上都运行良好。但是如果你在支持触摸屏的设备 上浏览网页的时候问题却来了,设备不支持鼠标,因此用户无法用鼠标来hover表格的title元素。用户唯一能和网页进行交互的设备就是用手指去触摸或 滑动屏幕,然而在一个非touch friendly的网页上用手指去触发传统的mouse hover事件会显得非常怪异,你会发现tooltip会在你手指接触到屏幕的一瞬间显示,而后马上会消失。这是因为浏览器默认触发了mouseover 和mouseout两个事件,而这两个事件只是在手指接触屏幕这一个操作中完成的,你根本没有办法去控制它。这只是许多不同中的一个小例子,还有很多不一 样的地方,如你在传统设备上用鼠标点击一个图片按钮不动用来连续不停地滚动DIV,而在触摸屏上浏览器会默认为你要显示右键菜单而阻止了该事件继续执行。 传统设备上通常情况下同一时间里系统只允许一个鼠标接受用户的操作,而触摸屏一般都支持多点触摸甚至支持各种不同的手势,如左右滑动、两只放大缩小和旋转 等。

  随着HTML5的发展,为了支持对触摸屏的操作,多个浏览器厂商都在自己的浏览器引擎中添加了很多支持touch的事件。但是由于W3C并没有 提供一个统一的标准,或者说该标准在不同的浏览器厂商中所遵循的情况也有很大区别,因此我们不得不针对浏览器版本做一些特殊的处理。这到让我想起了IE浏 览器在许多方面与其它浏览器的不同,这次也不例外!

 这里有一些页面介绍了在不同浏览器中对touch事件的支持,读者可以看一下它们之间到底有哪些不同。

  IE浏览器对touch事件的支持:http://blogs.msdn.com/b/ie/archive/2011/09/20/touch-input-for-ie10-and-metro-style-apps.aspx

  Firefox浏览器对touch事件的支持:https://developer.mozilla.org/en-US/docs/Web/Guide/Touch_events?redirectlocale=en-US&redirectslug=DOM%2FTouch_events

  基本上有两大阵营:IE浏览器和基于Webkit内核的浏览器。

       那么如何才能开发一个通用的支持touch事件的页面呢?基本上,我们只需要区别IE和Webkit内核的浏览器就行了,剩下的兼容性问题通常都比较好解决。MSDN的这个页面介绍了IE对指针和笔势事件的支持http://msdn.microsoft.com/zh-cn/library/ie/hh673557.aspx其中有讲到如何检测对指针事件的支持,我们可以利用该方法来区别IE和其它浏览器。看下面这个程序片段:

 

if (window.navigator.msPointerEnabled) {    /*Events for IE only*/
    document.getElementById("id0").addEventListener("MSPointerOver", function (e) {
          /*Add mouse over event for touch*/ 
        if (e.pointerType == e.MSPOINTER_TYPE_MOUSE) {
            methods.onMouseOver(this, e);
        }
    });
   document.getElementById("id0").addEventListener("MSPointerOut", function (e) {
                 /*Add mouse out event for touch*/
        if (e.pointerType == e.MSPOINTER_TYPE_MOUSE) {
            methods.onMouseOut(this, e);
        }
    });
    document.getElementById("id0").addEventListener("MSPointerDown", function (e) {
       if (e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
           /*Do something for touch input only*/
            methods.onTouchInput(this.parentNode);
        }        else {            /*Do something for non-touch input*/
            methods.onMouseClick(this.parentNode);
        }
    });
}
else {
     /*Events for non-IE or IE without msPointerEnabled*/
    $(this).bind("touchstart", function (e) {
        e.preventDefault();
        methods.onMouseClick(this.parentNode);
        methods.onMouseOver(this, e);
    });
     /*Common Mouse events: mouseover, mouseout, click*/
    $(this).click(function () {
          methods.onMouseClick(this); });
    $(this).hover( 
           function (e) {
                methods.onMouseOver(this, e);
            },
           function (e) { methods.onMouseOut(this, e); });
}

代码有两个主要的分支,针对IE和Webkit内核的浏览器。在IE浏览器中,MSPointerDown事件不会自动阻止鼠标事件,因此需要通过event.pointerType来判断指针类型。event.pointerType是一个枚举变量,一共有三个值:

  MSPOINTER_TYPE_TOUCH = 2

  MSPOINTER_TYPE_PEN = 3

  MSPOINTER_TYPE_MOUSE = 4

  很奇怪为什么没有值为1的枚举值?可能是用作保留了吧!这也就是说MSPointerDown事件在触发的同时还会触发鼠标相关的事件,事实上鼠标事件是最开始触发的。因此我们需要先判断指针类型,进行不同的处理。为了增加页面的兼容性,让其在支持鼠标操作的设备上也能有更好的体验,代码中特意添加了MSPointerOverMSPointerOut事件,并且判断当指针类型为MSPOINTER_TYPE_MOUSE时才去执行对应的鼠标事件。

  这里有几个兼容性问题需要考虑:

  1. Window.navigator.msPointerEnabled语句只会判断浏览器是否支持MSPointer相关的事件,而不会判断用户的设备是否支持触摸操作。目前只有在IE10上该对象不会返回undefined,其它版本的浏览器均视该对象不存在。如果你想判断用户的设备是否支持触摸操作,应该使用Window.navigator.msMaxTouchPoints,如果该对象存在并且返回的结果大于1,则表示设备支持触摸操作并且是支持多点触摸的。

  2. 在IE中,MSPointer相关的事件只会在浏览器支持的时候被触发,如果页面元素同时还带有鼠标事件,则鼠标事件也会被同时触发。

  3. Webkit内核的浏览器支持touchstart事件,MSPointer相关的事件在这些浏览器上被视为无效。通过e.preventDefault()语句可以阻止鼠标默认行为,从而不让mouse hover事件触发。

  所以,上面代码片段同时兼容了<IE10和IE10,以及兼容在IE10上的触摸和鼠标操作,和非IE内核的浏览器上的触摸和鼠标操作。有一个情况未考虑,那就是<IE10情况下的触摸操作,相信这种设备应该很难见到吧!

  当然,你完全可以将鼠标的Click事件当作touch事件来处理,如果元素上除了Click之外没有任何其它的事件。但是如果元素上还有 mouse hover相关的事件,则用户在touch的同时触发mouse hover,在这种情况下你或许可以考虑使用上面的逻辑来处理cross events。

其次就是各种尺度的不同宽高比(有时需要兼顾横屏的设计

    这个里面涉及到分辨率的问题,这个我目前还不太懂就不班门弄斧了大家可以看下这篇文章:

http://www.zhangxinxu.com/wordpress/2012/08/window-devicepixelratio/ 
关于横竖屏的问题:

无论是ipad还是安卓:

可以在function里面实装切换后的事件,比如横竖屏不同,画面的布局设计,css使用不同等等。

※你可以使用window.orientation来判断切换之后到底是横屏还是竖屏。


但是: 关于上面的代码,有几项是需要注意的。

1, window.orientation

    经过测试,在ipad,和andriod系统上面,window.orientation来判断横竖屏用得值正好相反。

window.orientation值参考:

  window.orientation 横竖屏结果
ipad 90或者-90 横屏
ipad 0 或者180 竖屏
Andriod 0 或者180 横屏
Andriod 90或者-90 竖屏


2,如何判断自己的设备是ipad还是安卓

 

//自动判断设备横屏or竖屏
var autoFullscreen = function () {
 var supportsOrientationChange = "onorientationchange" in window,
 orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";

 window.addEventListener(orientationEvent, function () {
  var ua = navigator.userAgent.toLowerCase();
  var deviceType = "";

  //determine device type
  if (ua.indexOf("ipad") > 0) {
   deviceType = "isIpad";
  } else if (ua.indexOf("android") > 0) {
   deviceType = "isAndroid";
  } else if (ua.indexOf("iphone") > 0) {
   deviceType = "isIphone";
  } else {
   return;
  }

  // 判断横竖屏  
  if ("isIpad" == deviceType) {
   if (Math.abs(window.orientation) == 90) {alert("我是ipad的横屏");  }
   else {alert("我是ipad的竖屏");  }
  } else if ("isAndroid" == deviceType) {
   //纵屏 90 or -90 横屏 0
   if (Math.abs(window.orientation) == 90) {alert("我是Android的纵屏");  }
   else {
    //document.webkitCancelFullScreen();

   alert("我是Android的横屏");  
   }
  } else if ("isIphone" == deviceType) {
   if (Math.abs(window.orientation) == 90) {}
   else {}
  }
 }, false);
}

第三个就是触摸和手机键盘的操作:这个里面涉及很多内容:推荐大家看下这个文章:http://lilin.hn.cn/201402279837.html 总结的很全面;在这里粘贴文章的一些内容:

如何关闭iOS中键盘自动大写
我们知道在iOS中,当虚拟键盘弹出时,默认情况下键盘是开启首字母大写的功能的,根据某些业务场景,可能我们需要关闭这个功能,移动版本webkit为 input元素提供了autocapitalize属性,通过指定autocapitalize=”off”来关闭键盘默认首字母大写。

iOS中如何彻底禁止用户在新窗口打开页面
有时我们可能需要禁止用户在新窗口打开页面,我们可以使用a标签的target=”_self“来指定用户在新窗口打开,或者target属性保持空,但 是你会发现iOS的用户在这个链接的上方长按3秒钟后,iOS会弹出一个列表按钮,用户通过这些按钮仍然可以在新窗口打开页面,这样的话,开发者指定的 target属性就失效了,但是可以通过指定当前元素的-webkit-touch-callout样式属性为none来禁止iOS弹出这些按钮。这个技 巧仅适用iOS对于Android平台则无效。

如何解决盒子边框溢出
当你指定了一个块级元素时,并且为其定义了边框,设置了其宽度为100%。在移动设备开发过程中我们通常会对文本框定义为宽度100%,将其定义为块级元 素以实现全屏自适应的样式,但此时你会发现,该元素的边框(左右)各1个像素会溢了文档,导致出现横向滚动条,为解决这一问题,我们可以为其添加一个特殊 的样式-webkit-box-sizing:border-box;用来指定该盒子的大小包括边框的宽度。

© 著作权归作者所有

武文海
粉丝 13
博文 97
码字总数 49318
作品 0
成都
高级程序员
私信 提问
加载中

评论(1)

天篷丿元帅
window.navigator.pointerEnabled 这个是什么东西啊?这是我在swiper插件中看到的
移动端布局与适配

grid实战之微信钱包 腾讯服务界面 CSS3网格布局是让开发人员设计一个网格并将内容放在这些网格内。而不是使用浮动制作一个网格,实际上是你将一个元素声明为一个网格容器,并把元素内容置于网...

掘金官方
2017/12/26
0
0
我想用手机测试自己写的web页面,该怎么做?

作者:不爱吃西红柿的鱼 链接:https://www.zhihu.com/question/37361845/answer/71674280 来源:知乎 一、IOS 移动端 (Safari开发者工具) 手机端:设置 → Safari → 高级 → Web 检查器 ...

hhj187
2016/10/16
26
0
web前端工程师的发展前景及工资待遇如何?

前端开发这个行业目前来说已经不算是个新兴的行业了,越来越多的人在这两年开始转型做Web前端开发,但是在2010年之前这个岗位还是很不受开发人员重视的,好一点的叫JS工程师,不好一点的叫美...

web前端03
2018/06/15
0
0
高手问答第 175 期 —— 沪江 iKcamp 团队前端高效开发实践分享

OSCHINA 本期高手问答(11 月 1 日 - 11 月 7 日)我们请来了@iKcamp团队为大家解答关于移动 Web 前端高效开发方面的问题。 “iKcamp团队”由沪江 Web 前端团队中热爱原创和翻译的小伙伴发起,...

局长
2017/10/31
2.6K
27
前端开发常见问题精选(二)

一、如何解决Canvas画布在移动端显示模糊的问题? Canvas画布在PC端显示正常,但是放在移动端却发现整个画布都有点模糊,其实这里有个比较简单的解决方法: 先给canvas标签的width和height这...

璿而不华
2017/09/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins系列_插件安装及报错处理

进入Jenkins之后我们可以进行插件的安装,插件管理位于以下模块: 发现上面报了一堆错误,是因为插件的依赖没有安装好,那么这一节,就先把这些错误解决掉吧。解决完成后,也就基本会使用插件...

shzwork
今天
2
0
mysql mysql的所有查询语句和聚合函数(整理一下,忘记了可以随时看看)

查询所有字段 select * from 表名; 查询自定字段 select 字段名 from 表名; 查询指定数据 select * from 表名 where 条件; 带关键字IN的查询 select * from 表名 where 条件 [not] in(元素...

edison_kwok
昨天
8
0
多线程同时加载缓存实现

import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorServi......

暗中观察
昨天
2
0
利用VisualVM 内存查看

准备工作,建几个测试类。等下就是要查看这几个类里面的属性 package visualvm;public class MultiObject { private String str; private int i; MultiObject(String str...

冷基
昨天
2
0
组装一台工作游戏两用机

一、配置清单如下: 分类 项目 价格(元) 主板 华硕(ASUS)TUF Z370-PLUS GAMING II 电竞特工 Z370二代 支持9代CPU 1049 CPU 英特尔(Intel) i7 8700K 酷睿六核 盒装CPU处理器 2640 风扇 九...

mbzhong
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部