javascript 是否可以制作一个应用内按钮来触发 PWA“添加到主屏幕”安装横幅?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50332119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 09:02:43  来源:igfitidea点击:

Is it possible to make an in-app button that triggers the PWA "Add to Home Screen" install banner?

javascriptservice-workerprogressive-web-apps

提问by Adam D

I understand that with a properly made Progressive Web App mobile browsers will display a banner prompting users to 'Install' the app on their home screen.

我知道使用正确制作的 Progressive Web App 移动浏览器将显示一个横幅,提示用户在其主屏幕上“安装”该应用程序。

I have been looking around for a way to trigger that prompt from within the app, but have not been able to find anything.

我一直在寻找一种从应用程序内触发该提示的方法,但一直找不到任何东西。

Is there a line of JavaScript that can be used to call the install prompt banner at any time?? Something that I could add to a install button tucked away in a help screen for instance?

有没有一行 JavaScript 可以随时调用安装提示横幅??例如,我可以添加到隐藏在帮助屏幕中的安装按钮的东西吗?

It might be difficult for some users to find the "Add to Home Screen" option if they missed the install banner prompt. I'd like to give them a button they can click to be prompted again.

如果某些用户错过了安装横幅提示,他们可能很难找到“添加到主屏幕”选项。我想给他们一个按钮,他们可以点击再次提示。

回答by Anand

Chrome(or any PWA supporting browser) triggers the beforeinstallpromptevent for Web app install banner, which you can catch and re-trigger in more appropriate time when you think user wont miss it/convinced about adding your site to home page. Starting Chrome version 68, catching beforeinstallprompt and handling the install prompt programmatically is mandatory and no banners will be shown automatically.

Chrome(或任何支持 PWA 的浏览器)触发Web 应用安装横幅的beforeinstallprompt事件,当您认为用户不会错过它/确信将您的网站添加到主页时,您可以在更合适的时间捕获并重新触发。从 Chrome 68 版开始,必须捕获 beforeinstallprompt 并以编程方式处理安装提示,并且不会自动显示横幅。

In case the user have missed the prompt/declined to add to home screen, the event can't be manually triggered by our code. This is intentionally left that way to avoid web pages annoying the users to repeatedly prompt the user for adding to home screen. Thinking of users perspective, this makes complete sense.

如果用户错过了提示/拒绝添加到主屏幕,则我们的代码无法手动触发该事件。这是故意留下的,以避免网页烦扰用户重复提示用户添加到主屏幕。从用户的角度考虑,这是完全有道理的。

Yes, there are cases when user miss the option accidentally and he may not know of the browser menu option to "Add to home screen" and it would be nice for us to trigger the same again. But unfortunately, that's not an option. At lest for now and I personally don't see that changing much considering how developers can abuse if its left to the developers to prompt.

是的,在某些情况下,用户不小心错过了该选项,并且他可能不知道“添加到主屏幕”的浏览器菜单选项,我们再次触发它会很好。但不幸的是,这不是一个选择。至少就目前而言,考虑到开发人员可以如何滥用,如果让开发人员提示,我个人认为这不会发生太大变化。

Alternate option:If the user have missed the install prompt or even chosen not to install it to home screen, give some time and when you think he is starting to like your site(based on conversions) you can show him a full page or half page Div popup kind of install instructions to add your site to home screen from browsers menu. It can have some images or Gif animation showing user how to add to home screen from the menu. With that, it should be self explanatory to most users, if not all.

替代选项:如果用户错过了安装提示,甚至选择不将其安装到主屏幕,请给一些时间,当您认为他开始喜欢您的网站时(基于转换),您可以向他展示整页或半页页面 Div 弹出式安装说明,可将您的网站从浏览器菜单添加到主屏幕。它可以有一些图像或 Gif 动画向用户展示如何从菜单添加到主屏幕。有了这个,它应该对大多数用户来说是不言自明的,如果不是全部的话。

Hereis some code example for the same, which is iOS specific(look under #PROTIP 3).

是相同的一些代码示例,这是特定于 iOS 的(查看 #PROTIP 3)。

As a bonus, you can show some promotions like discounts or added features when user add to home screen, which will convince user to do so. PWA has a way to find if the site is accessed form the home screen or browser.

作为奖励,您可以在用户添加到主屏幕时显示一些促销活动,例如折扣或添加的功能,这将说服用户这样做。PWA 有一种方法可以确定该站点是从主屏幕还是浏览器访问的。

For Development/testing:If you need this banner to come multiple times for dev/testing purpose, you can set the below flow in your Chrome for the same,

对于开发/测试:如果您出于开发/测试目的需要多次出现此横幅,您可以在 Chrome 中设置以下流程相同,

chrome://flags/#bypass-app-banner-engagement-checks

回答by AnthumChris

In mobile Chrome on Android, "Add to Home Screen" can be accessed from the browser's menu. (Similar options may exist for mobile Safari/Firefox on Android/iOS as well.) The web app manifest file is read and the app is added as it would be with the original prompt feature.

在 Android 上的移动 Chrome 中,可以从浏览器的菜单中访问“添加到主屏幕”。(Android/iOS 上的移动 Safari/Firefox 也可能存在类似的选项。)读取 Web 应用程序清单文件并添加应用程序,就像使用原始提示功能一样。

While JavaScript cannot be used to manually invoke the prompt, a workaround would be to provide on-screen instructions showing users how to manually open the menu and add for their specific user-agent.

虽然 JavaScript 不能用于手动调用提示,但解决方法是提供屏幕说明,向用户展示如何手动打开菜单并为他们的特定用户代理添加。

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

回答by Emmanuel Mahuni

There are events that browsers are now firing that help with the issue of handling installation of PWA's. It's not a web standard YET, but it's a good approach.

浏览器现在触发的一些事件有助于处理 PWA 的安装问题。这还不是网络标准,但它是一个很好的方法。

  • 'beforeinstallprompt' is fired right before the prompt is shown and
  • 'appinstalled' is fired right after the installation is complete.
  • 'beforeinstallprompt' 在提示显示之前被触发,并且
  • 'appinstalled' 在安装完成后立即触发。

So you can intercept 'beforeinstallprompt' event, prevent it from happening so that the banner doesn't show up, stash it for when you want the banner to show up, and finally create a button that a user clicks to then fire the earlier deferred event at will.

因此,您可以拦截“beforeinstallprompt”事件,防止它发生以便横幅不显示,将其隐藏以在您希望横幅显示时使用,最后创建一个用户单击的按钮,然后触发较早的延迟事件随意。

Below is a link about how to achieve this:

以下是有关如何实现此目标的链接:

https://web.dev/installable/discover-installable/codelab-make-installable

https://web.dev/installable/discover-installable/codelab-make-installable

回答by jeyloh

Well, there's nothing stopping you from storing the deferredPrompt value in a variable and use it later. Then you can popup a custom box, and if the user closes it down, you still haven't ran deferredPrompt.prompt() and can use it later. I store mine in Redux. If the user closes the install prompt, I use the deferredPrompt in the hamburger menu to install it at any time.

好吧,没有什么能阻止您将 deferredPrompt 值存储在变量中并在以后使用它。然后你就可以弹出一个自定义框,如果用户关闭了它,你仍然没有运行 deferredPrompt.prompt() 并且可以稍后使用它。我将我的存储在 Redux 中。如果用户关闭安装提示,我随时使用汉堡菜单中的 deferredPrompt 进行安装。

Listen to install and store event as prompt

根据提示收听安装和存储事件

 const beforeInstallListener = e => {
        // Prevent Chrome 76 and later from showing the install prompt
        e.preventDefault();
        // Stash the event so it can be triggered later.
        dispatch(setAndroidDeferredPrompt(e));
        dispatch(showAndroidPromptDownload(true));
    };
    window.addEventListener("beforeinstallprompt", beforeInstallListener);

Create a function which uses this deferredPrompt to prompt the user

创建一个使用此 deferredPrompt 提示用户的函数

    const installToAndroid = async () => {
    dispatch(showAndroidPromptDownload(false));
    deferredPrompt.prompt(); // Wait for the user to respond to the prompt
    const choiceResult = await deferredPrompt.userChoice;

    if (choiceResult.outcome === "accepted") {
        console.log("User accepted the PWA prompt");
    } else {
        closeAndroidPromptWithoutDownload();
        console.log("User dismissed the PWA prompt");
    }
    dispatch(setAndroidDeferredPrompt(null));
};

Remember, if the user clicks the banner to install, deferredPrompt.prompt() is invoked and it won't work anymore. Therefore I keep a check to see if deferredPrompt exists, and remember to set it to null if the user has invoked .prompt().

请记住,如果用户单击横幅进行安装,则会调用 deferredPrompt.prompt() 并且它将不再起作用。因此,我会检查是否存在 deferredPrompt,如果用户调用了 .prompt(),请记住将其设置为 null。

{deferredPrompt && <button onClick={() => installPWA(deferredPrompt)}>Installer til hjemskjerm</button>}

This was done with React Hooks, Redux and LocalStorage (where I store a pwa.reducer.js state)

这是通过 React Hooks、Redux 和 LocalStorage(我在其中存储 pwa.reducer.js 状态)完成的