【问题标题】:How to handle hardware back button in PWA developed using Ionic3如何在使用 Ionic3 开发的 PWA 中处理硬件后退按钮
【发布时间】:2017-12-06 12:25:07
【问题描述】:

我使用 Ionic 3 开发了一个 PWA(基于选项卡)。它工作正常,直到在 android 浏览器中按下硬件后退按钮或浏览器的后退按钮。如果它是从主屏幕运行,按硬件返回将关闭应用程序。如果应用程序在 android 中的 chrome 中运行(仅在 chrome 中测试),硬件背面或浏览器背面将重新加载 PWA 的第一页,而不是以前访问过的页面。如何在 Ionic 3 PWA 中处理这些事件?

我正在对所有页面使用延迟加载。

到目前为止我尝试了什么:

  1. 根据 jgw96 的评论 here,我认为 IonicPage 将自己处理导航。但它不起作用。

  2. 使用了 platform.registerBackButtonAction,但它不适用于 PWA。

  3. 根据下面 Webruster 在 Answers 中的建议,尝试了 app.component.ts 中的代码。但没有变化。

发帖代码:

    import { Component, ViewChild } from '@angular/core';
    import { Nav, Platform, AlertController, Alert, Events, App, IonicApp, MenuController } from 'ionic-angular';

    @Component({
      templateUrl: 'app.html'
    })
    export class MyApp {
      @ViewChild(Nav) nav: Nav;
      rootPage:any = 'TabsPage';
      constructor(public platform: Platform,
        public alertCtrl: AlertController, public events: Events,
          public menu: MenuController,
          private _app: App,
          private _ionicApp: IonicApp) {

        platform.ready().then(() => {
          this.configureBkBtnprocess ();
        });
      }

      configureBkBtnprocess() {
        if (window.location.protocol !== "file:") {
          window.onpopstate = (evt) => {
            if (this.menu.isOpen()) {
              this.menu.close ();
              return;
            }
    let activePortal = this._ionicApp._loadingPortal.getActive() ||
      this._ionicApp._modalPortal.getActive() ||
      this._ionicApp._toastPortal.getActive() ||
      this._ionicApp._overlayPortal.getActive();

    if (activePortal) {
      activePortal.dismiss();
      return;
    }

    if (this._app.getRootNav().canGoBack())
      this._app.getRootNav().pop();
          };

          this._app.viewDidEnter.subscribe((app) => {
            history.pushState (null, null, "");
            });
        }
      }
    }

【问题讨论】:

  • 那么你在期待什么,我的意思是在浏览器或硬件后退按钮上的应用程序中应该发生什么?
  • 如果我正在像 A->B->C 这样的页面导航,那么在 C 处的后按会弹出到 B。但在我的情况下,A 正在像新实例一样重新加载。
  • 用您尝试过的内容更新您的问题
  • 您能否发布您在 app.component.ts 中应用的更改的代码
  • @Webruster 请看代码,我已经贴出来了。

标签: android ionic-framework


【解决方案1】:

您提到您正在使用应用程序和浏览器中的硬件后退按钮,因此您没有清楚地提到在哪个阶段需要做什么,所以我想出了通用解决方案,该解决方案在大多数情况下都很有用案例

app.component.ts

platform.ready().then(() => {

      // your other plugins code...
      this.configureBkBtnprocess ();

    });

configureBkBtnprocess

private configureBkBtnprocess () {

    // If you are on chrome (browser)
    if (window.location.protocol !== "file:") {

      // Register browser back button action and you can perform
      // your own actions like as follows
      window.onpopstate = (evt) => {

        // Close menu if open
        if (this._menu.isOpen()) {
          this._menu.close ();
          return;
        }

        // Close any active modals or overlays
        let activePortal = this._ionicApp._loadingPortal.getActive() ||
          this._ionicApp._modalPortal.getActive() ||
          this._ionicApp._toastPortal.getActive() ||
          this._ionicApp._overlayPortal.getActive();

        if (activePortal) {
          activePortal.dismiss();
          return;
        }

        // Navigate back
        if (this._app.getRootNav().canGoBack()) 
        this._app.getRootNav().pop();

      }
      else{
        // you are in the app
      };

  // Fake browser history on each view enter
  this._app.viewDidEnter.subscribe((app) => {
    history.pushState (null, null, "");
  });

解决方案 2 尝试在准备好的平台中添加这些事件监听器:

 window.addEventListener('load', function() { window.history.pushState({}, '') 
           })
    window.addEventListener('popstate', function() { window.history.pushState({}, 
   '') })

【讨论】:

  • 这段代码是否经过测试或者您在某处使用它?我试过了,但没有用。同样的问题仍然存在。
  • @VivekSinha 没有测试过,你能告诉你尝试了什么案例吗? ,用你尝试过的最新代码更新问题
  • @V.Pivet 你能解释一下那个场景吗?
  • @Webruster 。我在安卓设备上。我在我的应用程序中导航,我按了我的后退按钮 2 次。第一次我的背部动作完成了,但第二次我的 pwa 接近了。
  • @V.Pivet 在平台准备好试试这个window.addEventListener('load', function() { window.history.pushState({}, '') }) window.addEventListener('popstate', function() { window.history.pushState({}, '') })
【解决方案2】:

我有几乎相同的要求,但没有一个解决方案完全有效,所以我想出了自己的。在这里,我使用了一个数组来跟踪访问过的页面并在返回点击事件时将其删除。

注意:window.onpopstate 在推送新页面时也会被调用

import { Platform, Nav } from "ionic-angular";
import { HomePage } from "../pages/home/home";
@Component({
  templateUrl: "app.html"
})
export class MyApp {
  rootPage: any;
  @ViewChild(Nav) nav: Nav;
  pageHistory: string[] = [];//to track page history

  constructor(
    platform: Platform,
    statusBar: StatusBar,
    splashScreen: SplashScreen
  ) {

    window.addEventListener("load", function() {
    //adding a state to prevent app exit on back
      window.history.pushState({ noBackExitsApp: true }, "");
    });

    platform.ready().then(() => {
      window.onpopstate = evt => {
        let view = this.nav.getActive();
        if (this.pageHistory.find(x => x === view.name)) {
          if (!view.name.startsWith("Home")) {//handle a condition where you want to go back
            this.pageHistory = this.pageHistory.filter(n => n !== view.name);
            this.nav.pop().catch(reason => {
              console.log("Unable to pop :" + reason);
            });
          }
        } else {
          window.history.pushState({ noBackExitsApp: true }, "");
          this.pageHistory.push(view.name);
        }
      };

      this.rootPage = HomePage;
      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 2017-01-26
    • 1970-01-01
    • 2015-04-30
    • 2019-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多