preface
In traditional Web applications, you can usually access the Web only by entering the corresponding URL in the browser’s address bar, or creating the Web address on the desktop by clicking and opening it in the browser.
In traditional mode, ICONS, splash screens, theme colors, view modes, screen orientation, and so on cannot be customized or controlled.
These functions can now be accomplished through features in the PWA standard that make the path to Web applications shorter and more visible, as described below.
The installation
Installing Web applications requires some preparation.
The installation conditions
Json file in the manifest.json file and add it to the page:
<link rel="manifest" href="./manifest.json" />
Copy the code
The following fields must be configured in the manifest.json file:
{
"short_name": "Short app name"."name": "Long app name"."icons": [{"src": "icons/192.png"."sizes": "144x144"."type": "image/png"}]."start_url": "."."display": "standalone",}Copy the code
Requirements:
- Run in HTTPS.
- Serviceworker must be registered and running.
- It must be in the manifest
icons
And at least144x144
的PNG
The image. - In the manifest
display
Set tostandalone
orfullscreen
. - It must be in the manifest
name
orshort_name
. - It must be in the manifest
start_url
. - In the manifest
prefer_related_applications
Not set or set tofalse
.
For detailed setup information on manifest, refer to the MANIFEST feature article written earlier.
Display installation prompts
Once configured as required, open the web site in the browser.
Android Chrome side
After Chrome 68, when the conditions for installing an application are met, the Mini Info bar pops up at the bottom of the browser. When you click the info bar, the Add to home screen dialog box is displayed. Click Add to complete the installation, and the app icon appears on the page.
Note: For Chrome 68-75, you can’t control the display of the Mini message bar by code. Chrome 76 and later supports code control. When the user clicks the “X” on the Mini message bar, the browser will not be prompted by the Mini bar for at least three months, but the event layer is not affected, which can be achieved by code.
PC Chrome side
Chrome 73 now supports Web installation from PC to desktop
Customize installation timing
When the Web application is fit for installation, the beforeInstallPrompt event is triggered and a prompt to install to the screen pops up. Based on this event, we can control whether the installprompt is displayed and when to install.
Beforeinstallprompt event is triggered every time the page is entered if the application is not installed, not if it is installed. This event will continue to be triggered after the user uninstalls the application.
Install prompt event capture logic:
var installPromptEvent = null;
window.addEventListener('beforeinstallprompt', (event) => {
event.preventDefault(); // Chrome <= 67 can block display
installPromptEvent = event; // Get a reference to the event
document.querySelector('#btn-install').disabled = false; // Update the installation UI to inform the user that the installation is available
});
Copy the code
The Prompt dialog box is displayed
A manual display of the installation dialog can be triggered by calling the prompt() method in the captured beforeInstallPrompt event reference.
Obtained through the outcome in the Promise result of the event userChoice property.
User clicks install logic:
document.querySelector('#btn-install').addEventListener('click', () = > {if( !installPromptEvent ) {
return;
}
installPromptEvent.prompt();
installPromptEvent.userChoice.then( choiceResult= > {
if (choiceResult.outcome === 'accepted') {
console.log('User has agreed to add to desktop')}else {
console.log('User unadded to desktop')}})})Copy the code
Event handling has been installed
You can use AppInstalled to listen to whether the application is installed:
window.addEventListener('appinstalled', (evt) => {
console.log('Installed to desktop screen');
});
Copy the code
Environmental judgment
You can use the display-mode attribute to determine whether the current application is opened by entering the URL in the browser or by using the desktop icon, and then set different interaction styles according to requirements.
Assume that the display set in the manifest is standalone
Js layer judgment:
if (window.matchMedia('(display-mode: standalone)').matches) {
console.log('the display - mode is standalone');
}
Copy the code
CSS layer judgment:
@media all and (display-mode: standalone) {
/** Custom style **/
}
Copy the code
Safari:
if (window.navigator.standalone === true) {
console.log('the display - mode is standalone');
}
Copy the code
Updates to applications
After the Web application is installed on the desktop, the update problem after the manifest is modified is different for each platform.
The Android end
On Android, Chrome checks the currently installed MANIFEST against the live Manifest when launching a Web application. If an update is required, it will automatically enter the update queue in wifi environment.
Trigger update rule:
- Update checking occurs only when the Web application is started. Launching Chrome directly does not trigger update checking for a given Web application.
- Chrome checks for updates every other day or every 30 days. Daily checking for updates happens most of the time. In cases where the update server is unable to provide updates, it switches to a 30-day interval.
- Clearing Chrome’s data (via “Clear All Data” in Android Settings) resets the update timer.
- If the Web Manifest URL is not changed, Chrome will only update the Web application. If you modify the manifest path of a web page, such as from
/manifest.json
Change to/manifest2.json
, the Web application will not be updated. (This is highly recommended) - Only Web applications created by the official Chrome (Stable/Beta/Dev/Canary) will be updated. It doesn’t work for Chromium (org.chromium.chrome).
- Update checking may be delayed until the connection is available with wifi.
PC
Update is not supported on PC, but may be supported later.
Compatible with
The current compatibility of this feature across platforms is as follows:
IOS adaptation
IOS requires a separate feature Meta for desktop ICONS, splash screens, app text, and theme colors.
Apple-touch-icon: indicates the application icon
Need to add:
<link rel="apple-touch-icon" href="/custom_icon.png">
Copy the code
Adaptation with different resolutions:
<link rel="apple-touch-icon" href="touch-icon-iphone.png">
<link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad.png">
<link rel="apple-touch-icon" sizes="180x180" href="touch-icon-iphone-retina.png">
<link rel="apple-touch-icon" sizes="167x167" href="touch-icon-ipad-retina.png">
Copy the code
Apple-touch-startup-image: startup screen
Need to add:
<link rel="apple-touch-startup-image" href="/launch.png">
Copy the code
Apple-mobile-web-app-title: Title of the app icon
By default, the value in
<meta name="apple-mobile-web-app-title" content="Application title">
Copy the code
Apple-mobile-web-app-status-bar-style: Specifies the appearance style of the application status bar
For example, set to black:
<meta name="apple-mobile-web-app-status-bar-style" content="black">
Copy the code
Compatible adaptation library
Normally, all features are subject to specification constraints, but Safari above is not, which increases the developer’s development costs.
So here’s an adaptation script, just write the manifest definitions in the specification, and leave the rest to the script.
(function(){function h(){var a=document.head.querySelector('link[rel="manifest"]'),b=a? a.href:"",d=A([b,window.location]);Promise.resolve().then(function(){if(! b)throw'can\'t find
\ ' ';var a={};"use-credentials"===b.crossOrigin&&(a.credentials="include");return window.fetch(b,a)}).then(function(a){return a.json()}).then(function(a){return B(a,d)}).catch(function(a){return console.warn("pwacompat.js error",a)})}function A(a){for(var b={},d=0; d<a.length; b={c:b.c},++d){b.c=
a[d];try{return new URL("",b.c),function(a){return function(b){return(new URL(b,a.c)).toString()}}(b)}catch(n){}}return function(a){return a}}function t(a,b){a=document.createElement(a);for(var d in b)a.setAttribute(d,b[d]);document.head.appendChild(a);return a}function c(a,b){b&&(!0===b&&(b="yes"),t("meta", {name:a,content:b}))}function B(a,b){function d(b,d,f){var k=b.width,c=b.height,e=window.devicePixelRatio; b=u({width:k*e,height:c*e}); b.scale(e,e); b.fillStyle=a.background_color||"#f8f9fa"; b.fillRect(0.0,k,c); b.translate(k/2,(c- 32) /2); b.font="24px HelveticaNeue-CondensedBold"; b.fillStyle=r?"white":"black"; k=b.measureText(v).width; f&&(c=f.width/e,e=f.height/e,128<e&&(c/=e/128,e=128),48<=c&&48<=e&&(b.drawImage(f,c/2 -,e/2 -,c,e),b.translate(0,e/2+32))); b.fillText(v,k/2 -.0); f=document.createElement("link"); f.setAttribute("rel"."apple-touch-startup-image"); f.setAttribute("media"."(orientation: "+d+")"); f.setAttribute("href",b.canvas.toDataURL());return f}function n(a){var b=d(window.screen,"portrait", a); a=d({width:window.screen.height,height:window.screen.width},"landscape",a); w.forEach(function(a){return a.remove()});document.head.appendChild(b);document.head.appendChild(a); w.add(b); w.add(a)}varg=a.icons||[]; g.sort(function(a,b){return parseInt(b.sizes,10) -parseInt(a.sizes,10)});var x=g.map(function(a){a={rel:"icon".href:b(a.src),sizes:a.sizes}; t("link",a);if(p)return a.rel="apple-touch-icon",t("link",a)}),q=a.display; g=- 1! ==C.indexOf(q); c("mobile-web-app-capable",g); D(a.theme_color||"black");
E&&(c("msapplication-starturl",a.start_url||"/"),c("msapplication-TileColor",a.theme_color));document.head.querySelector('[name="theme-color"]')||c("theme-color",a.theme_color);varh=F(a.orientation); c("x5-orientation",h); c("screen-orientation",h);"fullscreen"===q? (c("x5-fullscreen"."true"),c("full-screen"."yes")):g&&(c("x5-page-mode"."app"),c("browsermode"."application"));if(p){var r=y(a.background_color||"#f8f9fa"),v=a.name||a.short_name||document.title; (q=G(a.related_applications))&&c("apple-itunes-app"."app-id="+q); c("apple-mobile-web-app-capable",g); c("apple-mobile-web-app-title",v);var w=new Set; n(null);if(x.length){var m=x[0],l=newImage; l.crossOrigin="anonymous"; l.onload=function(){n(l);if(a.background_color){var b=z(l,a.background_color);null! ==b&&(m.href=b,x.slice(1).forEach(function(b){var d=newImage; d.crossOrigin="anonymous"; d.onload=function(){var c=z(d,a.background_color,!0); b.href=c}; d.src=b.href}))}}; l.src=m.href}}}function G(a){varb; (a||[]).filter(function(a){return"itunes"===a.platform}).forEach(function(a){a.id?
b=a.id:(a=a.url.match(/id(\d+)/))&&(b=a[1])});return b}function F(a){a=String(a||""); a=a.substr(0.3);return"por"===a?"portrait":"lan"===a?"landscape":""}function D(a){if(p||H){var b=y(a);if(p)c("apple-mobile-web-app-status-bar-style",b?"black":"default");else{try{var d=Windows.UI.ViewManagement.ApplicationView.getForCurrentView().titleBar}catch(n){d=null}null===d?console.debug("UWP no titleBar"):(d.foregroundColor=r(b?"black":"white"),d.backgroundColor=r(a))}}}function r(a){a=m(a);return{r:a[0].g:a[1].b:a[2].a:a[3]}}function m(a){varb=u(); b.fillStyle=a; b.fillRect(0.0.1.1);return b.getImageData(0.0.1.1).data}function y(a){a=m(a).map(function(a){a/=255;return03928.>a? a/12.92:Math.pow((a+055.) /1.055.2.4)});return 3<Math.abs(1.05/ (2126.*a[0] +7152.*a[1] +0722.*a[2] +.05))}function z(a,b,d){d=void 0===d? !1:d;varc=u(a); c.drawImage(a,0.0);if(! d&&255==c.getImageData(0.0.1.1).data[3])return null; c.globalCompositeOperation="destination-over"; c.fillStyle=b; c.fillRect(0.0,a.width,a.height);return c.canvas.toDataURL()}
function u(a){a=void 0===a? {width:1.height:1}:a;var b=a.height,c=document.createElement("canvas"); c.width=a.width; c.height=b;return c.getContext("2d")}if("fetch"in window) {var C=["standalone"."fullscreen"."minimal-ui"],p=navigator.vendor&&- 1! ==navigator.vendor.indexOf("Apple"),E=navigator.userAgent&&- 1! ==navigator.userAgent.indexOf("Edge"),H="undefined"! = =typeof Windows;"complete"= = =document.readyState? h():window.addEventListener("load",h)}})();
Copy the code
Invoke the address: http://unpkg.alipay.com/[email protected]/pwacompat.min.js.
Use:
<link rel="manifest" href="./manifest.json" />
<script src="http://unpkg.alipay.com/[email protected]/pwacompat.min.js" crossorigin="anonymous"></script>
Copy the code
Blog name: Wang Leping blog
CSDN blogs at blog.csdn.net/lecepin