如何在使用Ionic3开发的PWA中处理硬件返回按钮

xwbd5t1u  于 2023-04-18  发布在  Ionic
关注(0)|答案(2)|浏览(122)

我开发了一个PWA(基于标签)使用离子3.它工作正常,直到硬件返回按钮或浏览器的返回按钮在Android浏览器中按下.如果它是从主屏幕运行,按硬件返回将关闭应用程序.如果应用程序在Android中的Chrome中运行(仅在chrome中测试),硬件或浏览器的背面将重新加载PWA的第一页,而不是以前访问过的页面。如何在Ionic 3 PWA中处理这些事件?
我对所有页面都使用延迟加载。
到目前为止,我尝试的是:
1.根据jgw96在这里的评论,我以为IonicPage会自己处理导航。但它不工作。
1.使用platform.registerBackButtonAction,但它不适用于PWA。
1.根据Webruster在下面的答案中的建议,尝试了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, "");
            });
        }
      }
    }
knpiaxh1

knpiaxh11#

你提到你正在使用应用程序和浏览器上的硬件返回按钮,所以你没有清楚地提到在哪个阶段需要做什么,所以我提出了在大多数情况下都有用的通用解决方案

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尝试在platform ready中添加这些事件监听器:

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

t40tm48m2#

我有几乎相同的要求,但没有一个解决方案完全工作,所以我想出了我自己的。在这里,我使用了一个数组来跟踪访问过的页面,并在返回单击事件中删除它。
注意: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();
    });
  }
}

相关问题