为本站添加A2HS

Author Avatar
huuhghhgyg 7月 27, 2019
  • 在其它设备中阅读本文章
终究止不住折腾,终于还是把卡住很久的这个功能做出来了。

参考文档

manifest的设置

一开始的时候瞎瞄两眼介绍,就天真地以为只要manifest.json或者manifest.webmanifest这个文件存在就好了,结果后来慢慢了解发现还有事呢..反正让它跑起来再说…

不管怎么说,先把manifest.webmanifest写好 (当然你写manifest.json也是可以的,只不过时改了一下后缀名而已,内容相同,看哪个顺眼就用哪个)
那既然要这个文件,就先找最简单的抄了一个,内容如下(来自Mozilla A2HS demo)

{
  "background_color": "purple",
  "description": "Shows random fox pictures. Hey, at least it isn't cats.",
  "display": "fullscreen",
  "icons": [
    {
      "src": "icon/fox-icon.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ],
  "name": "Awesome fox pictures",
  "short_name": "Foxes",
  "start_url": "/pwa-examples/a2hs/index.html"
}

反正这些属性会英文的都看得懂,照着改就是了。值得一提的有两个属性:

  • icons:这个属性我觉得其实挺狗的,按照 Google Developers 上面的要求,至少要有192x192512x512两种尺寸的图标。反正那个时候我被hexo坑住了,以为这是硬性规定,所以就用格式工厂强行转化出了这两种尺寸的图标。后来发现并不是这样,因为我现在的icons属性内容如下:
        "icons": [{
            "src": "~.png",
            "sizes": "720x720",
            "type": "image/png"
        },
        {
            "src": "~.png",
            "sizes": "192x192",
            "type": "image/png"
        }
        ],
    
    (此处隐去文件目录)
    所以应该是最好这么做,让浏览器有缩放的空间,因为 Google Developers上有这么一句话

    成功:包括192x192像素图标和512x512像素图标。Chrome会自动缩放设备的图标。如果您希望缩放自己的图标并将其调整为完美像素,请以48dp的增量提供图标。(来自机翻)

  • start_url:这里参考了一下友链中的网站,发现了他的manifest.webmanifest中有这样的一行"start_url": ".",,所以我猜只要根目录下存在index.html并且这个文件被设为为默认主页的话只需要如上设置就可以了。

manifest的生效

manifest文件需要被引用才会生效,所以要在<head>里面加入引用如下<link rel="manifest" href="manifest.webmanifest">。需要注意的是,经过多次实验,引用的这行标签必须放在<head>里面才会生效,其他地方则无效。 (没错,这就是我被hexo坑的地方)

根据Google Developers上的资料,manifest文件生效还有如下几点:

  • 完整的基本属性。(参见开头链接)
  • https连接
  • serviceworker的存在(或许是?)

最终结果

Ctrl+C & Ctrl+V 的ServiceWorker

说实话我也完全不懂这到底是怎么回事,但是大概知道ServiceWorker是注册服务的,有弹出横幅的功能。

应该是来源于manifest.js中。
首先添加manifest.js的引用<script src="manifest.js" defer></script>(来源于开头的demo)

manifest.js的内容如下

// Register service worker to control making site work offline

if ('serviceWorker' in navigator) {
    navigator.serviceWorker
        .register('serviceworker.js')
        .then(function() { console.log('Service Worker Registered'); });
}

// Code to handle install prompt on desktop

let deferredPrompt;
const addBtn = document.querySelector('.add-button');
addBtn.style.display = 'none';

window.addEventListener('beforeinstallprompt', (e) => {
    // Prevent Chrome 67 and earlier from automatically showing the prompt
    e.preventDefault();
    // Stash the event so it can be triggered later.
    deferredPrompt = e;
    // Update UI to notify the user they can add to home screen
    addBtn.style.display = 'block';

    addBtn.addEventListener('click', (e) => {
        // hide our user interface that shows our A2HS button
        addBtn.style.display = 'none';
        // Show the prompt
        deferredPrompt.prompt();
        // Wait for the user to respond to the prompt
        deferredPrompt.userChoice.then((choiceResult) => {
            if (choiceResult.outcome === 'accepted') {
                console.log('User accepted the A2HS prompt');
            } else {
                console.log('User dismissed the A2HS prompt');
            }
            deferredPrompt = null;
        });
    });
});

发现两个问题:

  1. manifest.js内部还存在引用.js文件sw.js,内容如下:

     self.addEventListener('install', function(e) {
     e.waitUntil(
     caches.open('video-store').then(function(cache) {
         return cache.addAll([
         '/pwa-examples/a2hs/',
         '/pwa-examples/a2hs/index.html',
         '/pwa-examples/a2hs/index.js',
         '/pwa-examples/a2hs/style.css',
         '/pwa-examples/a2hs/images/fox1.jpg',
         '/pwa-examples/a2hs/images/fox2.jpg',
         '/pwa-examples/a2hs/images/fox3.jpg',
         '/pwa-examples/a2hs/images/fox4.jpg'
         ]);
     })
     );
     });
    
     self.addEventListener('fetch', function(e) {
     console.log(e.request.url);
     e.respondWith(
         caches.match(e.request).then(function(response) {
         return response || fetch(e.request);
         })
     );
     });
    

    说明这是安装时执行的脚本,我觉得部分脚本对我的情况来说还是存在实际意义的,于是去掉了demo中的存储本地媒体的动作内容,修改后如下:

     self.addEventListener('fetch', function(e) {
         console.log(e.request.url);
         e.respondWith(
             caches.match(e.request).then(function(response) {
                 return response || fetch(e.request);
             })
         );
     });
    
     self.addEventListener('install', function(e) {
         e.waitUntil(
             caches.open('video-store').then(function(cache) {
                 return cache.addAll([
    
                 ]);
             })
         );
     });
    

    最终复制到了manifest.webmanifest的同目录下。

  2. 打开浏览器后报错说addBtn.style.display = 'none';无法执行。经实践发现demo中有一个button <button class="add-button">Add to home screen</button> 经查,这是充当电脑版浏览器中引发”添加至主屏幕弹窗”事件的按钮,所以只要在页面中给他找个地方放上就行了。要是在原有页面上修改的话记得把要充当这个button的组件上加个class="add-button"即可。

关于引用插入到hexo中的<head>

可能时由于hexo-material这个主题的关系,经实践表明hexo\themes\material\layout\_partial\head.ejs中注释Custom-head的标签所在位置已经在<body>的地方了!所以我把插入<link rel="manifest" href="manifest.webmanifest">的地方稍微提前到了注释WebAPP Icons的上一行,总算被Chrome识别出来了。

At last

假期差不多结束了,应该不会有什么更新了。See ya!

link
本文链接:
发文时间
7月 27, 2019
请遵循协议