Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone Safari Web App opens links in new window

I found JavaScript solution in iWebKit framework:

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

The other solutions here either don't account for external links (that you probably want to open externally in Safari) or don't account for relative links (without the domain in them).

The html5 mobile-boilerplate project links to this gist which has a good discussion on the topic: https://gist.github.com/1042026

Here's the final code they came up with:

<script>(function(a,b,c){if(c in b&&b[c]){var d,e=a.location,f=/^(a|html)$/i;a.addEventListener("click",function(a){d=a.target;while(!f.test(d.nodeName))d=d.parentNode;"href"in d&&(d.href.indexOf("http")||~d.href.indexOf(e.host))&&(a.preventDefault(),e.href=d.href)},!1)}})(document,window.navigator,"standalone")</script>

If you are using jQuery, you can do:

$("a").click(function (event) {
    event.preventDefault();
    window.location = $(this).attr("href");
});

This is working for me on iOS 6.1 and with Bootstrap JS links (i.e dropdown menus etc)

$(document).ready(function(){
    if (("standalone" in window.navigator) && window.navigator.standalone) {
      // For iOS Apps
      $('a').on('click', function(e){
        e.preventDefault();
        var new_location = $(this).attr('href');
        if (new_location != undefined && new_location.substr(0, 1) != '#' && $(this).attr('data-method') == undefined){
          window.location = new_location;
        }
      });
    }
  });

This is an old question and many of the solutions here are using javascript. Since then, iOS 11.3 has been released and you can now use the scope member. The scope member is a URL like "/" where all paths under that scope will not open a new page.

The scope member is a string that represents the navigation scope of this web application's application context.

Here is my example:

{
  "name": "Test",
  "short_name": "Test",
  "lang": "en-US",
  "start_url": "/",
  "scope": "/",
  ...
}

You can also read more about it here. I also recommend using the generator which will provide this functionality.

If you specify the scope, everything works as expected similar to Android, destinations out of the scope will open in Safari — with a back button (the small one in the status bar) to your PWA.


Based on Davids answer and Richards comment, you should perform a domain check. Otherwise links to other websites will also opened in your web app.

$('a').live('click', function (event)
{      
    var href = $(this).attr("href");

    if (href.indexOf(location.hostname) > -1)
    {
        event.preventDefault();
        window.location = href;
    }
});

If using jQuery Mobile you will experience the new window when using the data-ajax='false' attribute. In fact, this will happen whenever ajaxEnabled is turned off, being by and external link, by a $.mobile.ajaxEnabled setting or by having a target='' attribute.

You may fix it using this:

$("a[data-ajax='false']").live("click", function(event){
  if (this.href) {
    event.preventDefault();
    location.href=this.href;
    return false;
  }
});

(Thanks to Richard Poole for the live() method - wasn't working with bind())

If you've turned ajaxEnabled off globally, you will need to drop the [data-ajax='false'].

This took me rather long to figure out as I was expecting it to be a jQuery Mobile specific problem where in fact it was the Ajax linking that actually prohibited the new window.