admin管理员组文章数量:1328020
I have added service-worker.js and manifest to my website and tested the page using lighthouse which shows my webpage is ready to show "Add to home screen" to user. But the prompt doesn't shows up twice if user closes the tab without dismissing the prompt first time.Is there any other way to achieve this?. Here is my manifest
{
"short_name": "TestApp",
"name": "Long Name",
"icons": [
{
"src":"images/favicon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src":"images/favicon-256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src":"images/favicon-384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src":"images/favicon-512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"background_color": "#fff",
"theme_color": "#d2d2d2",
"display": "standalone"
}
here is my service worker javascript file
/*
Copyright 2015 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in pliance with the License.
You may obtain a copy of the License at
.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
// Incrementing CACHE_VERSION will kick off the install event and force previously cached
// resources to be cached again.
const CACHE_VERSION = 3;
let CURRENT_CACHES = {
offline: 'offline-v' + CACHE_VERSION
};
const OFFLINE_URL = 'offline.html';
function createCacheBustedRequest(url) {
let request = new Request(url, {cache: 'reload'});
// See
// This is not yet supported in Chrome as of M48, so we need to explicitly check to see
// if the cache: 'reload' option had any effect.
if ('cache' in request) {
return request;
}
// If {cache: 'reload'} didn't have any effect, append a cache-busting URL parameter instead.
let bustedUrl = new URL(url, self.location.href);
bustedUrl.search += (bustedUrl.search ? '&' : '') + 'cachebust=' + Date.now();
return new Request(bustedUrl);
}
self.addEventListener('install', event => {
event.waitUntil(
// We can't use cache.add() here, since we want OFFLINE_URL to be the cache key, but
// the actual URL we end up requesting might include a cache-busting parameter.
fetch(createCacheBustedRequest(OFFLINE_URL)).then(function(response) {
return caches.open(CURRENT_CACHES.offline).then(function(cache) {
return cache.put(OFFLINE_URL, response);
});
})
);
});
self.addEventListener('activate', event => {
// Delete all caches that aren't named in CURRENT_CACHES.
// While there is only one cache in this example, the same logic will handle the case where
// there are multiple versioned caches.
let expectedCacheNames = Object.keys(CURRENT_CACHES).map(function(key) {
return CURRENT_CACHES[key];
});
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (expectedCacheNames.indexOf(cacheName) === -1) {
// If this cache name isn't present in the array of "expected" cache names,
// then delete it.
console.log('Deleting out of date cache:', cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
self.addEventListener('fetch', event => {
// We only want to call event.respondWith() if this is a navigation request
// for an HTML page.
// request.mode of 'navigate' is unfortunately not supported in Chrome
// versions older than 49, so we need to include a less precise fallback,
// which checks for a GET request with an Accept: text/html header.
if (event.request.mode === 'navigate' ||
(event.request.method === 'GET' &&
event.request.headers.get('accept').includes('text/html'))) {
console.log('Handling fetch event for', event.request.url);
event.respondWith(
fetch(event.request).catch(error => {
// The catch is only triggered if fetch() throws an exception, which will most likely
// happen due to the server being unreachable.
// If fetch() returns a valid HTTP response with an response code in the 4xx or 5xx
// range, the catch() will NOT be called. If you need custom handling for 4xx or 5xx
// errors, see
console.log('Fetch failed; returning offline page instead.', error);
return caches.match(OFFLINE_URL);
})
);
}
// If our if() condition is false, then this fetch handler won't intercept the request.
// If there are any other fetch handlers registered, they will get a chance to call
// event.respondWith(). If no fetch handlers call event.respondWith(), the request will be
// handled by the browser as if there were no service worker involvement.
});
I have added service-worker.js and manifest to my website and tested the page using lighthouse which shows my webpage is ready to show "Add to home screen" to user. But the prompt doesn't shows up twice if user closes the tab without dismissing the prompt first time.Is there any other way to achieve this?. Here is my manifest
{
"short_name": "TestApp",
"name": "Long Name",
"icons": [
{
"src":"images/favicon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src":"images/favicon-256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src":"images/favicon-384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src":"images/favicon-512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"background_color": "#fff",
"theme_color": "#d2d2d2",
"display": "standalone"
}
here is my service worker javascript file
/*
Copyright 2015 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in pliance with the License.
You may obtain a copy of the License at
http://www.apache/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
// Incrementing CACHE_VERSION will kick off the install event and force previously cached
// resources to be cached again.
const CACHE_VERSION = 3;
let CURRENT_CACHES = {
offline: 'offline-v' + CACHE_VERSION
};
const OFFLINE_URL = 'offline.html';
function createCacheBustedRequest(url) {
let request = new Request(url, {cache: 'reload'});
// See https://fetch.spec.whatwg/#concept-request-mode
// This is not yet supported in Chrome as of M48, so we need to explicitly check to see
// if the cache: 'reload' option had any effect.
if ('cache' in request) {
return request;
}
// If {cache: 'reload'} didn't have any effect, append a cache-busting URL parameter instead.
let bustedUrl = new URL(url, self.location.href);
bustedUrl.search += (bustedUrl.search ? '&' : '') + 'cachebust=' + Date.now();
return new Request(bustedUrl);
}
self.addEventListener('install', event => {
event.waitUntil(
// We can't use cache.add() here, since we want OFFLINE_URL to be the cache key, but
// the actual URL we end up requesting might include a cache-busting parameter.
fetch(createCacheBustedRequest(OFFLINE_URL)).then(function(response) {
return caches.open(CURRENT_CACHES.offline).then(function(cache) {
return cache.put(OFFLINE_URL, response);
});
})
);
});
self.addEventListener('activate', event => {
// Delete all caches that aren't named in CURRENT_CACHES.
// While there is only one cache in this example, the same logic will handle the case where
// there are multiple versioned caches.
let expectedCacheNames = Object.keys(CURRENT_CACHES).map(function(key) {
return CURRENT_CACHES[key];
});
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (expectedCacheNames.indexOf(cacheName) === -1) {
// If this cache name isn't present in the array of "expected" cache names,
// then delete it.
console.log('Deleting out of date cache:', cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
self.addEventListener('fetch', event => {
// We only want to call event.respondWith() if this is a navigation request
// for an HTML page.
// request.mode of 'navigate' is unfortunately not supported in Chrome
// versions older than 49, so we need to include a less precise fallback,
// which checks for a GET request with an Accept: text/html header.
if (event.request.mode === 'navigate' ||
(event.request.method === 'GET' &&
event.request.headers.get('accept').includes('text/html'))) {
console.log('Handling fetch event for', event.request.url);
event.respondWith(
fetch(event.request).catch(error => {
// The catch is only triggered if fetch() throws an exception, which will most likely
// happen due to the server being unreachable.
// If fetch() returns a valid HTTP response with an response code in the 4xx or 5xx
// range, the catch() will NOT be called. If you need custom handling for 4xx or 5xx
// errors, see https://github./GoogleChrome/samples/tree/gh-pages/service-worker/fallback-response
console.log('Fetch failed; returning offline page instead.', error);
return caches.match(OFFLINE_URL);
})
);
}
// If our if() condition is false, then this fetch handler won't intercept the request.
// If there are any other fetch handlers registered, they will get a chance to call
// event.respondWith(). If no fetch handlers call event.respondWith(), the request will be
// handled by the browser as if there were no service worker involvement.
});
Share
Improve this question
asked May 30, 2017 at 6:45
yaseryaser
1991 gold badge2 silver badges11 bronze badges
2 Answers
Reset to default 5I could be wrong with this one but if your user has not clicked on the Accept button, I think that is a considered Dismissed.
The only time that your user will be able to see that again is if they cleared their cache and browser settings for that particular site.
Google has also documented:
Source: https://developers.google./web/updates/2015/03/increasing-engagement-with-app-install-banners-in-chrome-for-android
You can create better UX, like ask user if they want to install app or by showing install app icon somewhere then ask browser to show the banner.
Right now (Apr 2018) Google updated PWA documentations and it shows developer can decide when to prompt "Add to Home Screen" and they provided a sample code.
Same UX tips described here to ask user for notifications permission.
Here is the sample code they provided:
var deferredPrompt;
window.addEventListener('beforeinstallprompt', function(e) {
console.log('beforeinstallprompt Event fired');
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
return false;
});
btnSave.addEventListener('click', function() {
if(deferredPrompt !== undefined) {
// The user has had a positive interaction with our app and Chrome
// has tried to prompt previously, so let's show the prompt.
deferredPrompt.prompt();
// Follow what the user has done with the prompt.
deferredPrompt.userChoice.then(function(choiceResult) {
console.log(choiceResult.oute);
if(choiceResult.oute == 'dismissed') {
console.log('User cancelled home screen install');
}
else {
console.log('User added to home screen');
}
// We no longer need the prompt. Clear it up.
deferredPrompt = null;
});
}
});
本文标签: javascriptAdd to home screen prompt doesn39t show up again if tab is closedStack Overflow
版权声明:本文标题:javascript - Add to home screen prompt doesn't show up again if tab is closed - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742244060a2439016.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论