-->

How do you keep an iPhone/iPad web app in full scr

2019-01-16 08:05发布

问题:

I have an HTML5 iPad app that works offline. The app essentially consists of 4 html files and 3 aspx files. My cache manifest is setup so that only the html files are available offline, and the aspx files require a network connection. This is all working great!

Now, I've gotten to the point where I'm putting the finishing touches on the app and trying to finalize the home screen icons, running in full screen mode, etc. I've added what I believe are the necessary meta tags to make the app initially launch in full screen mode once it's been added to the home screen. The reason I believe the tags are correct is that the app will (correctly) launch and stay in full screen mode if I navigate back and forth between the html pages. The problem I'm having is getting the app to stay in full screen mode when one of the server (aspx) links are clicked.

When a server link (aspx) is clicked Mobile Safari kicks out into full browser mode and opens a new window. This behavior is not acceptable and I'm hoping that I'm missing something simple here.

Here are the meta tags I'm using on all of my pages (html + aspx):

  <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />

Hopefully this provides all of the necessary information needed to understand the problem. I have seen other links on here stating that ANY page other than the one bookmarked on the home page causes some folks to exit full screen mode. This is not the problem I'm having, so I wanted to start a new discussion. Again, I feel that if I had 5 more html pages in the app it would continue to stay in full screen mode. The aspx pages are the problem in my situation.

回答1:

Let the computer do the tedious job, that's what they're made for.

This is a piece of javascript code I use to avoid rewriting all my links. With that, only those links that have an explicit target = "_blank" attribute will open in Safari. All other links will remain inside the web app.

var a=document.getElementsByTagName("a");
for(var i=0;i<a.length;i++) {
    if(!a[i].onclick && a[i].getAttribute("target") != "_blank") {
        a[i].onclick=function() {
                window.location=this.getAttribute("href");
                return false; 
        }
    }
}


回答2:

Heres a jQuery plugin that could help: https://github.com/mrmoses/jQuery.stayInWebApp

Its a similar javascript solution, but has a few more features. By default it will attach to all links, but you can use it to attach to links with a certain class or something. It also detects iOS full screen mode so that it doesnt get in the way of other browsers and devices.



回答3:

In my experience, any external link seems to cause the app to jump out of full-screen mode. One solution is to manage your navigation using javascript and the location object. As follows:

HTML:

<a href="javascript:navigator_Go('abc.aspx');">Go</a> 

Javascript:

function navigator_Go(url) {
    window.location.assign(url); // This technique is almost exactly the same as a full <a> page refresh, but it prevents Mobile Safari from jumping out of full-screen mode
}

I know it's a pain to have to rework your links in this way, but it is the only way I have found to solve the problem you are facing.



回答4:

The problem with KPM's solution is that it messes with all links in all pages of your app, sometimes causing hard-to-find bugs, especially if your app is ajax intensive. I found a much better solution here on github.

I am reproducing the code below for the sake of convenience:

(function(document,navigator,standalone) {
            // prevents links from apps from oppening in mobile safari
            // this javascript must be the first script in your <head>
            if ((standalone in navigator) && navigator[standalone]) {
                var curnode, location=document.location, stop=/^(a|html)$/i;
                document.addEventListener('click', function(e) {
                    curnode=e.target;
                    while (!(stop).test(curnode.nodeName)) {
                        curnode=curnode.parentNode;
                    }
                    // Condidions to do this only on links to your own app
                    // if you want all links, use if('href' in curnode) instead.
                    if('href' in curnode && ( curnode.href.indexOf('http') || ~curnode.href.indexOf(location.host) ) ) {
                        e.preventDefault();
                        location.href = curnode.href;
                    }
                },false);
            }
        })(document,window.navigator,'standalone');


回答5:

The solution I've settled with is Waypoints for handling internal links. It has an open() method for external links which works up until iOS 6. After which you need this other fix for iOS 7.

// Internal link handling
Waypoints
  .intercept('a')
  .ignore('a[rel=external], a[rel=blank], a[target=_blank], a[href$=".pdf"]');
  // .resume();

// External link handling...
$('a').on('click', function(e) {
  var href = $(this).attr('href');

  if ($(this).is('a[rel=external], a[rel=blank], a[target=_blank], a[href$=".pdf"]') || (href.indexOf('http') >= 0 && href.indexOf(document.location.host) === -1)) {
    e.preventDefault();
    var link = this;

    if (navigator.standalone) {
      if (/iP(hone|od|ad) OS 7/.test(navigator.userAgent)) {
        // iOS 7 external link polyfill
        e.stopPropagation();

        // Your custom dialog code for iOS 7 and external links
      }
      else {
        Waypoints.open(href);
      }
    }
    else {
      window.open(href);
    }
  }
});

There's also Swipy.js you should check out, it includes Waypoints as a library and I might include all this link handling and the iOS 7 fix if it's worth it.



回答6:

Adding this to index file will do the trick.

 <head>
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-touch-fullscreen" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">

  <script type”javascript="" text”="">
      document.addEventListener(‘DOMContentLoaded’, function(){
         var updateStatusBar = navigator.userAgent.match(/iphone|ipad|ipod/i) && navigator.appVersion.match(/OS (\d)/) && parseInt(navigator.appVersion.match(/OS (\d)/)[1], 10) >= 7 && window.navigator.standalone;
         if (updateStatusBar) {
             document.body.classList.add(‘platform-ios’);
             document.body.classList.add(‘platform-cordova’);
         }
       });
  </script>