简体   繁体   中英

history.back doesn't work on iOS using Cordova

I have a hybrid application developed with Cordova. The app is very simple, so I haven't used a framework. Almost all the pages are injected via Ajax using the jQuery's ajax() method, and then added in the history using the HTML5 History API via the pushState() method.

To allow the user to go back to a previously visited page (a page in the history), I've created a button. I listen for the backbutton event as well as taps on that button and when the event is fired, I execute the following handler:

onBackButton: function() {
   window.history.length === 0 ? navigator.app.exitApp() : window.history.back();
}

To be sure to have the maximum compatibility possible, I've also added history.js to the project.

It works like a charm on Android and on the iOS simulator on the Mac, but doesn't work on a real device. What happens is that iOS catch the event but the execution of the method doesn't change the page. I've already tried several methods based on previous answers on StackOverflow, but no luck. Some examples are: history.back() not working in phonegap ios build and Phonegap - navigator.app.backHistory() not working on HTML back button .

What I can try?

You can simply use,

history.go(-1);

to navigate back.

Try this one.

main.js

var pagesHistory = [];
var currentPage = {};
var path = "";

page1.js

currentPage = {};
currentPage.back = function() {
    pagesHistory.pop();
};
currentPage.loadPage2 = function() {
    pagesHistory.push(path + "pages/Page2.html");
};

page2.js

currentPage = {};
currentPage.back = function() {
    pagesHistory.pop();
};
currentPage.loadPage1 = function() {
    pagesHistory.push(path + "pages/Page1.html");
};

Reference: http://public.dhe.ibm.com/software/mobile-solutions/worklight/docs/v620/BuildingMultiPageApplicationProject.zip

Seen this answer from a few months back? Apparently iOS has some security issues when it comes to navigating history through script alone. The answer here also includes a work around by hashing the URLs: StackOverflow Question

Dont know if cordova itself has the navigator.. but I usually used this function for going back:

function goBack() {
    //or history.back()
    history.go(-1);
    navigator.app.backHistory();
}

Could not test it though.

Edit: Since you don't do full refresh and load almost everything through ajax, you maybe have to implement the history back yourself.. the iphone has some problems with javascript only pages when going back. Since you push your actions to the history it shouldn't be to hard:

window.addEventListener("popstate", function(e) {
    //get it from the history, execute your functions to show the page as usual
});

app.application.navigate("#:back")怎么样?

I don't use the Cordova, but this code might help you:

String . prototype . isEmpty = function () { return this . length === 0; };

var browserHistory;

function hash ( name, historyChange )
{
    "use strict";
    if ( name !== undefined )
    {
        if ( hash () !== name )
        {
            if ( ! historyChange ) { browserHistory . add ( name ); }
            window . location . hash = name;
        }
    }
    else
    {
        var newHash = window . location . hash . split ( "#" ) [ 1 ];
        return newHash === undefined ? "" : newHash;
    }
}

browserHistory =
{
    currentIndex : 0,
    history : [],
    add : function ( name )
    {
        "use strict";
        this . currentIndex = this . currentIndex + 1;
        if ( this . history . length - 1 > this . currentIndex ) { this . history . splice ( this . currentIndex ); }
        this . history . push ( name );
    },
    backward : function ()
    {
        "use strict";
        if ( this . currentIndex === 0 ) { return; }
        this . currentIndex = this . currentIndex - 1;
        this . changeHash ();
    },
    changeHash : function ()
    {
        "use strict";
        hash ( this . history [ this . currentIndex ], true );
    },
    forward : function ()
    {
        "use strict";
        if ( this . currentIndex === this . history . length - 1 ) { return; }
        this . currentIndex = this . currentIndex + 1;
        this . changeHash ();
    },
    init : function ( name )
    {
        "use strict";
        this . history . push ( name );
    }
};

window . onhashchange = function ()
{
    "use strict";
    if ( hash () . isEmpty () ) { load ( { name: "" } ); }
    else { load ( { name: hash () } ); }
};

window . onload = function ()
{
    "use strict";
    if ( ! hash () . isEmpty () )
    {
        browserHistory . init ( hash () );
        load ( { name: hash () } ); 
    }
    else { browserHistory . init ( "" ); }
};

This script:
1) Work with sites that uses hashes ( http(s)://(www.)name.domain/#urlHash ).

Examle:
https://www.example.com/page - default url
https://www.example.com/page#login - login subpage
https://www.example.com/page#images - images subpage
etc.

2) "window . onload" function check if entered url contain a hash and init browserHistory with it or with: "" ( empty string ) - no hash is my main page
3) "browserHistory" object save a page history
4) "hash" function called without arguments returns current url hash and with "name" parameter change url hash
5) When hash is changed "window . onhashchange" function is called
6) "window . onhashchange" function check hash
If the url does not contain hash, script load the default page.
If the url contain a hash, script load a subpage based on hash.
7) In function "load" ( not described here ) I have an XMLHttpRequest, that call php file with name argument and set to main div element html code that was returned from that php file.
8) Instead of ( for example ):

<a class="a_nice_style" href="https://www.example.com/images.html>Images gallery</a>

You can use ( for examle ):

<p class="a_nice_style" onclick="hash ( 'images' );">Images gallery</p>

9) Function named: "load" have an object as a parameter. This object is send to php file ( as an "$_GET" or "$_POST" array ), so you can call "load" function with custom object that contains for example login fields values.
10) "browserHistory" have only hashes of your page.

This will be your button onclick function:

onBackButton: function() { browserHistory . backward (); }

You can modify a "browserHistory . backward" function to exit your app by replace: "return;" in this line:

if ( this . currentIndex === 0 ) { return; }

with your application exit code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM