为了给某个网页或者整个网站指定一个漂亮的教程桌面启动图标,iOS Safari提供了两个私有接口: apple-touch-icon
和 apple-touch-icon-precomposed
。全攻
通过在页面HTML的教程头部添加 <link>
标签
- <link rel="apple-touch-icon" href="touch-icon-iphone.png" />
- <link rel="apple-touch-icon-precomposed" href="touch-icon-precomposed.png" />
这两个标签都是用来指定桌面图标的,但两者有个细微的全攻区别,
apple-touch-icon
添加的教程图标是会带iOS图标统一的高光效果apple-touch-icon-precomposed
添加的图标则是设计原图,不带高光渐变效果的全攻。为了给不同的教程iOS设备指定其启动图标,在iOS Human Interface Guide中提到,全攻推荐以下四种尺寸:
iOS设备 | 最适尺寸(px) |
---|---|
iPhone 和 iTouch | 57 x 57 |
retina iPhone 和 retina iTouch | 114 x 114 |
iPad | 72 x 72 |
retina iPad | 144 x 144 |
相应地,教程要指定不同分辨率的全攻设备的图标,可以添加相应的教程 <link>
标签序列,官方建议的顺序是这样的
- <link rel="apple-touch-icon" href="touch-icon-iphone.png" />
- <link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad.png" />
- <link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone-retina.png" />
- <link rel="apple-touch-icon" sizes="144x144" href="touch-icon-ipad-retina.png" />
通过 <link>
的 <sizes>
属性可以特别地声明这个图标是为哪种分辨率设备准备的,如果没有指明 <sizes>
属性的大小,则默认值为57×57。
如果所有的 <link>
标签序列中都没有符合官方推荐的最适尺寸的话,那么iOS会从所有比推荐的最适尺寸大的图标中选择尺寸最小的那一个,如果所有的 <link>
标签序列中的图标都比当前推荐的最适尺寸小的话,iOS会从这些图片中自动选择最大的那个来作为启动图标。
特别地,如果整个页面都没有指定任何的 apple-touch-icon
的图标的话,iOS则会自动去网站根目录寻找有 apple-touch-icon
和 apple-touch-icon-precomposed
前缀的图标文件。
用于设置成为桌面启动图标的图片文件,可以是以下三种类别
/files/uploadimg/20130522/1005102.png
但如果是动态gif图片只会截取一帧(第一帧?)来显示
image/png
文件头的请求。就像我们常用的图片http://getimg.in/144x144tcat
这个的优点是可以根据前端需要动态地返回不同的图片,缺点是,每次新的图片都需要请求服务器,从服务器下载
base64格式的图片这是一个包含png文件头的长字符串,它可以是一张从静态图片转换的,也可以是从服务器返回的,还可以是canvas生成的。
data:image/png;base64,(xxxxxx)
#p#
首先需要声明的是,webapp不能像nativeapp一样后台推送,在没打开前是不运行的,而webapp里所有的js逻辑都只有在页面打开状态下才能运行,所以动态修改桌面启动图标的方法只有在每次点开后才能生效。
基于此,动态桌面图标的使用并不适合比如天气、新闻、twitter等即时性很高、后台主动推送的场景,仅仅适用于用户每次手动打开后便更新内容,更新完之后的icon能作为一个状态的标识供用户参考,比如任务管理工具、记帐软件等。
使用base64的优点是,可以选择由canvas来动态生成,并且不需要有网络请求,直接在本地完成。
而且我们的场景非常特殊:仅iOS的Safari,所以完全可以不用考虑浏览器的支持度。
- var canvas = document.createElement('canvas');
- canvas.width = 144;
- canvas.height = 144;
- var context = canvas.getContext("2d");
- var baseImg = canvas.toDataURL();
<link>
标签桌面图标在页面里的声明仅仅存在 <link>
中,理论上我们只要动态修改 <link>
标签的图片地址就能实现动态的图标。
首次从safari里将页面添加主屏幕时,iOS会检查页面里的 <link>
标签,读取图片的地址然后生成启动图标。并且这个标签只要在用户执行这步操作之前就有的,即不管是页面模板里静态本来存在的,还是通过js动态创建的,该方法一样生效。
http://av.cm/tick/test/DefaultLink.html
http://av.cm/tick/test/ClickAddLink.html
我们期望的场景是,用户在webapp里进行了一项操作,这个操作更新了整个webapp的状态,我们希望这个状态的改变能在桌面的启动图标里体现出来。
拿task工具来举例,用户在点开之前,桌面图标上显现任务队列里还有3个任务,当添加了一个新的任务之后,桌面图标上的任务数字应该变成4。当所有的任务都被打勾完成之后,桌面图标也应该反馈这样的状态,比如显示0条任务或者其它鼓励类的图标。
所以理论上,我们要做的就是在每次操作之后,通过js在一个canvas中绘出新的图案,再将这个canvas转化成base64的图片,动态创建到一个 <link>
标签添加至head就行了。
但事实上并不是这样。
当在webapp里创建了一个 <link>
再退出后,发现桌面的启动图标并没有像我们期望的那样被更新。
经过死乞白赖的测试后发现,在webapp里进行添加和修改的 <link>
标签并不能被iOS读取和渲染到,虽然 <link>
标签在页面里的确存在着,但并不会被更新到桌面。因为webapp里的图标是在body.onload的时候被渲染的。
是的,尽管这样听上去很不科学,但是他还是发生了。下面的两个demo的功能都把webapp打开的次数画进canvas,然后生成到桌面图标里,只不过第一个demo的添加方法是在 body.onload
时触发,第二个是在用户点击操作时才触发。
http://av.cm/tick/test/BodyLoadSetIcon.html本页面将在每次body.onload事件后读出打开的次数,生成下面的图片,并把这个图片添加至head。先添加页面至主屏幕,在webapp模式下打开再退出检查桌面启动图标。图标上的数字标识出页面被打开的次数,在每次打开再退出后图标上的数字将加1。
http://av.cm/tick/test/ClickSetIcon.html本页面在载入的时页面头部并没有link标签,通过点击操作读出打开的次数,生成下面的图片,并把这个图片添加至head。先添加页面至主屏幕,在webapp模式下打开再退出检查桌面启动图标。在每次打开再退出后图标上的数字始终没有被修改。
既然已知图标是在 body.onload
时被渲染的,那么我们需要在每次操作之后都要进行一次reload操作,并且在body.onload的时候再生成图片添加 <link>
标签。为了保证在每次页面重载的时候状态不丢失,需要把状态保存起来,考虑到webapp特殊的使用场景和环境,使用LocalStorage就非常方便。
所以,更新桌面图标的方法都应该绑定在 body.onload
上,整个流程看上去应该这个样子的:
<link>
添加到 <head>
里location.reload()
重新载入一次页面,执行第一步。基本上所有与更新Icon的关键逻辑都在 body.onload
时执行完毕,其它的中间态都只是对状态的更新。
这里有一个简单的DEMO,以webapp形式实现的任务工具。主要演示了上面提到的更新桌面启动图标的逻辑。
http://av.cm/tick/
第一次添加到主屏幕时显示的是从Safari里默认的初始图片(这里是一个灯泡),当更新了任务列表之后,桌面上的启动图标将会显示任务列表里未完成的任务,除此之外:
navigation.standalone
判断当前网页是否以webapp运行。如果不是则显示添加到主屏幕的提示。你还可以在github上查看详细的代码,并且如果愿意的话提出改进。
Try and enjoy it.
webapp因为权限的原因,尚不能做到:
但是,Apple在iOS设备的主屏幕上为webapp开了一扇窗户,我们也许可以通过这扇窗为用户带来特别的体验。
责任编辑:徐川 来源: 腾讯ECD iOSWeb Appicon(责任编辑:知识)
价格揭晓!荣耀50系列发布:首发骁龙778G、最高100W快充
一致性评价正在有条不紊的推进中 莎普爱思新药研发驱动产业升级
华阳股份(600348.SH)公布消息:拟开展应收账款保理业务