簡體   English   中英

如何處理使用Ionic3開發的PWA中的硬件后退按鈕

[英]How to handle hardware back button in PWA developed using Ionic3

我使用Ionic 3開發了一個PWA(基於Tab)。它在Android瀏覽器中按下硬件后退按鈕或瀏覽器后退按鈕之前工作正常。 如果它從主屏幕運行,按回硬件將關閉應用程序。 如果應用程序在android中運行chrome(僅在chrome中測試),硬件返回或瀏覽器的后面將重新加載PWA的第一頁,而不是之前訪問過的頁面。 如何在Ionic 3 PWA中處理這些事件?

我正在為所有頁面使用延遲加載。

到目前為止我嘗試了什么:

  1. 按照jgw96的評論在這里 ,我想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, "");
            });
        }
      }
    }

你已經提到你正在使用應用程序和瀏覽器中的硬件后退按鈕,所以你沒有清楚地提到在什么階段需要做什么,所以我提出了在大多數情況下都有用的通用解決方案

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({}, 
   '') })

我有幾乎相同的要求,但沒有一個解決方案完全有效,所以我想出了自己的。 在這里,我使用了一個數組來跟蹤訪問過的頁面,並在后退點擊事件中刪除它。

注意:即使在推送新頁面時也會調用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();
    });
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM