三个月前曾写过一篇跨终端响应式页面设计入门的博客,上了博客园头条也获得了很多关注,今天想在这篇博客的基础上,继续写一篇进阶的文章。css
补充html
基于“入门”一文,我想再补充几个基础知识点,主要都是针对iOS的meta标签:ios
⑴ 容许全屏浏览页面的标签:web
<meta name="apple-mobile-web-app-capable" content="yes" />
⑵ safari顶端状态栏样式定义/隐藏:chrome
<meta name="apple-mobile-web-app-status-bar-style" content="blank" /> <!--隐藏状态栏--> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <!--定义状态栏样式为暗黑色-->
⑶ ios会把相似电话号码的数字变为可点击并添加到电话的链接,咱们能够这样禁用它:api
<meta name="format-detection" content="telephone=no" />
另外还有一个个性化的link标签,它支持用户将网页建立快捷方式到桌面时,其图标变为咱们本身定义的图标。好比手机腾讯网上的标签:移动web开发
<link rel="apple-touch-icon-precomposed" href="http://3gimg.qq.com/wap30/info/info5/img/logo_icon.png">
不过腾讯对这个png图标的命名并不规范,常规咱们要求文件名应为 apple-touch-icon.png 或 apple-touch-icon-precomposed.png ,前者的命名iOS会为这个图标自动添加圆角、阴影和高亮覆盖层,后者则不会添加这些效果。浏览器
提高app
移动端web的开发最头疼的是viewport与常规PC页面的不一样,若是你的页面是专门针对移动端开发的(特别是使用了meta标签禁止用户缩放),这个头疼的程度会舒缓不少。iphone
我的以为,对viewport的深刻理解,也算打通入门移动web开发的任督二脉之一吧。
咱们依旧拿“移动端访问博客园”的图例来分析:
不少新入门移动端开发的朋友都会误觉得上图的绿线是窗口的宽度($(window).width())、红线部分是窗口的高度($(window).height()),但其实否则,任什么时候候都不该该把PC浏览器的窗口概念跟移动端的viewport混淆在一块儿。
那么移动端难道没有窗口宽高?非也,只是正确的“窗口宽高”(称为viewport的宽高会更靠谱些)应该是这样的(依旧用绿线和红线表示):
要注意这两个值,不管你怎么双指缩放页面,它们的大小都是不会变更的(除非页面内容发生了变化,好比动态生成了一张很大的的img撑大了页面)。
那么究竟一开始咱们“误觉得”了的那个伪窗口的宽高,分别是什么呢?
它们分别是 window.innerWidth 和 window.innerHeight —— 页面实际可视区域所展示的像素宽值/高值:
或许你会以为有点可笑,认为直接称两者为“页面实际可视区域宽高”不就好了。
其实“所展示的像素”仍是不该当舍弃的,由于两者的值是变化的,跟随着用户缩放页面而变化,咱们拿window.innerWidth来示例:
除了上述的,还有一个可能有用的值,它能够获取设备屏幕宽高,它包含了顶端系统状态栏、浏览器导航条的宽高值,它们是 screen.width 和 screen.height :
相信你也会想到,若是咱们的页面是专门针对移动端设计的页面(页面初始化铺满屏幕宽度,且禁用了缩放功能的移动端响应式页面,例如手机腾讯网),那么 $(window).width() 、window.innerWidth、screen.width 的值将是相等的(手机QQ内置浏览器等奇葩浏览器除外)。
既然说到“页面初始化铺满屏幕宽度,且禁用了缩放功能”这个事,咱们再顺便打个岔聊一下。其功能的实现其实就是添加“入门”一文介绍过了的meta标签:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
在“入门”中我也已经介绍过,除了这个标签,咱们还应当在其下增长一行:
<meta name="MobileOptimized" content="320">
最近公司的一个移动端旧项目遇到一个挺好玩的事情跟这个有关,该项目页面没有添加MobileOptimized标签,而后又使用了基于jQuery的swipe.js,而后在其它手机上都能正常显示幻灯片:
但到了iphone 4S- 下就发生了图片错位的事情:
这是由于swipeJS并不会对浏览器窗口大小变化进行从新布局调整(你能够用PC访问这里而后缩放窗口试试),而旧版的iphone会默认把页面作980宽度渲染,但最终以320像素宽度显示,因此才致使了幻灯片图片错位的问题。
能够得知添加 MobileOptimized 标签,告知ios要以320像素的宽度渲染页面也是很重要的事情。
咱们再说说手势,有时候移动端项目不免会须要一些手势的支持,而咱们也有一些很出众的手势库(好比已经进化到2.0版本的harmmerJS)可供选择。不过若是项目对手势的要求不复杂,却是不必引入额外的手势库,本身实现一个便可。
常规各类手势库都不外乎是基于一下三个事件来实现的:
ontouchstart
ontouchmove
ontouchend
顾名思义,就是触碰开始、移动、结束时的事件。要注意jQuery对touch系列的支持略麻烦,如事件句柄应再加上一句“originalEvent”(如“e.targetTouches[0].clientX”要写为“e.originalEvent.targetTouches[0].clientX”),建议直接使用addEventListener来实现:
function dragObj(obj){ var $obj = obj, obj = obj.get(0), startX, startY, _x,_y; obj.addEventListener('touchstart', function (e) { startX = e.targetTouches[0].pageX; startY = e.targetTouches[0].pageY; }); obj.addEventListener('touchmove', function (e) { _x = e.targetTouches[0].pageX - startX; _y = e.targetTouches[0].pageY - startY; $obj.css({"left":$obj.offset().left+_x,"top":$obj.offset().top+_y}); startX = e.targetTouches[0].pageX; startY = e.targetTouches[0].pageY; e.preventDefault(); }); } dragObj($("div"));
如上方轻松实现了一个拖拽的手势库,其中e.targetTouches[0]表示首个触碰点,咱们能够经过e.targetTouches[0].pageX、e.targetTouches[0].pageY 来得到该触点的页面坐标(相对viewport而不是屏幕可视区域),其它的相信都能看得懂也无需逐个介绍了。
要着重提醒的是,在不少移动端浏览器(UC啊QQ啊等)上,若是不添加 e.preventDefault() ,会致使touchmove事件仅触发一次(原生chrome却是没有此问题),因此必定要在touchmove事件中加上这句代码。
至于另外一个可能经常使用到的缩放手势,咱们能够经过判断touchstart和touchend先后的window.innerWidth是否一致,若是不一致则说明页面被缩放了。
其它经常使用api
一. 摇一摇
像淘宝的“摇一摇手机得到红包”活动,咱们能够经过devicemotion方法轻松实现,虽然event.accelerationIncludingGravity这名字长的有点夸张(但也比webGL一堆难记的api好多了):
var mobile_motion = { speed: 25, x: 0, y: 0, z: 0, lastX: 0, lastY: 0, lastZ: 0 } $(window).on("devicemotion", function () { var acceleration = event.accelerationIncludingGravity, speed = mobile_motion.speed; mobile_motion.x = acceleration.x; mobile_motion.y = acceleration.y; if (parseInt(flag.isWave_cur) && !flag.isShow_act && (Math.abs(mobile_motion.x - mobile_motion.lastX) > speed || Math.abs(mobile_motion.y - mobile_motion.lastY) > speed)) { //这里填写回调事件 } mobile_motion.lastX = mobile_motion.x; mobile_motion.lastY = mobile_motion.y; })
经过修改speed值能够实现调速,就是要摇多快才能触发回调。
二. 翻转屏幕
屏幕翻转的事件更简单,经过orientationchange方法来监听便可:
$win.on("orientationchange", function () { //回调事件 })
屏幕在初始化或者翻转后,都会有一个表明横屏仍是竖屏的值—— window.orientation,经过判断其值,咱们能够得知屏幕当前状态,甚至知道它是进行了怎样的翻转(好比从竖屏顺时针转90度到横屏),关于它们的值能够点这里看看,本文就不具体介绍了。