注:本文主要记录了创建一个PWA应用的过程,方便日后再次开发类似应用时参考。
github链接:shenlvmeng/Distance: 一次PWA的尝试
准备
安装http-server方便本地测试。
本地开辟文件夹,加入.editorconfig
和.gitignore
(根据样例适当修改)
|
|
创建index.html
|
|
在目标文件夹路径下执行http-server
,bingo!第一步完成
清单文件
创建清单文件manifest.json
,描述应用添加到主屏幕需要的信息。
|
|
并在index.html
中引入:
|
|
添加Service Worker
Service Worker这个东西可以实现页面的缓存和离线访问,让应用逼近app的体验。
可以在HTML里插入<script>
标签引入,这里单独定义一个app.js。
|
|
在index.html
中引用。
下面实现service worker。主要是三个时机:
- 脚本安装时,写入缓存
- 脚本获取数据时,先查找缓存
- 缓存更新版本时,删除原先版本的缓存
|
|
其中,有下面一些名词:
self
: Service Worker作用域, 也是全局变量caches
: 缓存接口waitUntil
,ExtendableEvent.waitUntil()
方法——这会确保Service Worker 不会在waitUntil()
里面的代码执行完毕之前安装完成。skipWait
,表示强制当前处在waiting状态的脚本进入activate状态
在浏览器中打开localhost:8080/
即可,注意PWA必须运行在HTTPS的环境下。
加入百度地图支持
参考官方API接入支持。
添加文件index.js
,写入如下内容:
|
|
当然需要添加一点CSS,这里从略。
Service Worker支持跨域
接下来问题来了,打开网页测试,页面刷新时Service Worker会抛出跨域相关的错误。
再正常不过了,未经配置的情况下,fetch是不允许跨域的。注意sw.js
中的一段:
|
|
这里我们不仅有跨域请求,还使用着JSONP的方式。后续地图数据和地图图片的展示请求也比较复杂。再经过多次加入respondWith()
响应块失败后,干脆跳过这部分跨域的处理。不过还是留下了一个函数,方便后面拓展。
|
|
目标点管理
核心功能之一是,可以新增计算距离的目标点。在我的设计里,有两种用户友好的添加方式:
- 找不到地点时,可以搜索出地点,通过搜索结果设置
- 明确地图上位置时,直接通过鼠标操作设置
前面的利用AutoComplete类,完成自动补全和搜索功能。值得注意的一个坑是,在初次设置好map对象后,每次的搜索结果都会以第一次初始化地点为中心搜索结果。解决方案是,每次<input>
框聚焦时,重新构造一个AutoComplete类。
|
|
|
|
下一步是支持标记点(BeaconNodes)的管理,离线持久化采用localStorage
,技术上倒没有什么难度。用户交互上,考虑用右键点击(for PC)和长按操作(PC Mobile)添加,点击标记删除。
|
|
在管理上,新增了下拉菜单管理当前所有节点,这里需要将离线的BeaconNodes映射成DOM结构,考虑到文件已略大,且这一部分比较繁琐,和业务关系不大,故单独抽出一个文件。
|
|
HTML和CSS部分就不再赘述了。
在下拉菜单下,可以点击条目跳转到相应位置,以及点击按钮切换当前活动的BeaconNode。这部分实现如下:
|
|
当然了,标记点的增删改查还剩下改没有实现,目前来看,和“改”相关的业务是能拖动标记点,方便用户随时更改标记点位置。在addBeacon()
函数中新增相关代码。
|
|
而editToBeacons()
函数设计如下:
|
|
计算距离
计算距离包括距离和方向两部分,既然能拿到两点的经纬度信息,这两个值肯定可以计算出来。计算距离上利用百度地图的API,计算角度上,通过Math.atan2
换算得到。
|
|