iPhone Safari Web App bağlantıları yeni pencerede açar


155

Ana Ekrana simge ekledikten sonra web ile ilgili sorun yaşıyorum. Web Ana Ekrandan başlatılırsa, tüm bağlantılar Safari'de yeni pencerede açılır (ve tam ekran işlevselliğini kaybeder). Nasıl önleyebilirim? Herhangi bir yardım bulamadım, sadece aynı cevaplanmamış soru.


3
Şimdi içindeki scopeparametreyi kullanabilirsiniz manifest.json. Daha fazla ayrıntı için cevabıma bakın. İOS 11.3'te test ettim ve işe yarıyor.
Amir Raminfar

3
Tekrarlamak için, iOS 11.3 Safari'yi açarak mücadele eden herkes için, lütfen @ AmirRaminfar'ın cevabına bakınız: stackoverflow.com/a/49604315/32055
Chris Haines

Yanıtlar:


110

JavaScript çözümünü iWebKit çerçevesinde buldum :

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

25
Açık olanı belirtmek ve bunu açıkça belirtmek için: iOS, Web Uygulamalarındaki bağlantıları Safari'de açılması gereken bir şey olarak ele alır ve javascript konumu, web uygulamasında saty'ye izin verilen bir uygulama içi eylem olarak değişir. Yukarıdaki kod, varsayılan bağlantı davranışını engellediğinden, bir js nav çağrısıyla değiştirildiği için çalışır.
Oskar Austegard

6
Aksine bir örnek var mı? Bir iPhone web uygulamasını, bir javascript konum değişikliği olmasına rağmen Safari'de bir sayfa açmaya zorluyor musunuz?
tkahn

1
@Pavel iwebkit'den bahsettiğiniz için teşekkür ederim :). Biraz trafik almaya yardımcı olur: D
cmplieger

3
[].forEach.call(document.links, function(link) { link.addEventListener("click", function(event) { event.preventDefault(); window.location = this.href; }) });
alex

1
Bunun herhangi bir yan etkisi var mı?
pingu

94

Buradaki diğer çözümler ya harici bağlantıları (muhtemelen Safari'de harici olarak açmak istediğinizi) veya göreli bağlantıları (içinde alan olmadan) hesaba katmaz.

Html5 mobile-boilerplate projesi, bu konuda iyi bir tartışmaya sahip olan bu öze bağlantı veriyor: https://gist.github.com/1042026

İşte geldikleri son kod:

<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>

Bu, bir sayfa, şirketimiz için "Bize ulaşın" sayfası dışında harika çalışıyor. Sayfayı göstermek yerine, "Haritalar" uygulamasını açar ve ofisimizi belirler. Buna ne neden olabilir ve nasıl düzeltebiliriz?
Jonathan

@Jonathan emin değilim. Bu komut dosyasını kaldırırsanız gerçekleşmez mi? Belki sitenize bir bağlantı gönderin? Veya yeni bir soru açın, bu daha iyi olabilir.
rmarscher

@rmarscher Bu yalnızca sağladığınız kodu çalıştırırken olur, onsuz değil. Ben bir web geliştiricisiyim ve neden bağlantıyı bu şekilde ele alacağını anlamıyorum. Bir sayfa URL'm yok çünkü şu anda kodu çalıştırmadığından fark etmeyeceksiniz. Ayrıca, sadece tek başına değil, normal Safari'yi de etkiler. Cevabınız için teşekkürler!
Jonathan

Bu, kabul edilen yanıt olmalı ve PHPRunner ile yapılan iPad1 tam ekran istemcimde, kodu başlığa yerleştirerek bir cazibe çalıştı. Neden çok BW yükü olmadan okunaklı yazılabilecek oldukça kısa bir kod parçası gibi neden bu kadar şaşkın emin değilim ... Bu sadece seçici olsa da ve genellikle gerçekten söylemek istiyorum.
sradforth

4
Bu, js işlevleri tarafından kullanılan href = "#" bağlantıları gibi Bootstrappy şeylerini kırar
Sean

47

JQuery kullanıyorsanız şunları yapabilirsiniz:

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

1
Lütfen .live () neden daha iyi olabilir?
ajcw

8
live, etkinliği henüz mevcut olmayanlar da dahil olmak üzere tüm bağlantılara bağlar, tıklama yalnızca şu anda mevcut olanlara bağlanır
msaspence

Teşekkürler! cankurtaran. Safari'nin neden sürekli yüklendiğini anlamaya çalışmak için saatler harcadım.
Steve

1
Benden +1 - this.hrefbir jQuery nesnesine yayınlamak yerine kullanılır , ancak bu cevap için teşekkürler. İOS6'da çalışır.
Fenton

17
() .live olan jQuery 1.7 itibarıyla kaldırıldı ve 1.9 ile çıkarıldı . Bunun yerine $ (document) .on ('tıklama', 'a', işlev () {...}) kullanın.
Tom Davies

21

Bu benim için iOS 6.1'de ve Bootstrap JS bağlantılarında (örn. Açılır menüler vb.)

$(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;
        }
      });
    }
  });

1
+1. Bu aslında bağlantıları düzeltmeden önce bir web uygulaması kullanıp kullanmadığınızı kontrol eder.
arabası

1
İOS 8.0.2'de çalışıyor! Teşekkürler
Joel Murphy

1
@sean Ben href olarak bir görüntü haritası kullanan bir iPad çalışan başka bir webapp var ve bu kod çalışmıyor ... Diğer tüm bağlantılar için iyi çalışıyor. Bu kodun görüntü haritalarıyla nasıl çalışacağına dair bir fikrin var mı? Tüm yığını kopyalamayı ve $('a').on('click'işlev (e) {`ile işlev (e) {` 'yi değiştirmeyi denedim $('area').on('click'ama bu da işe yaramıyor. Herhangi bir fikir?
nematoth

Eğer zaten üzerinde tanımlı tıklama işlevlere sahip aolan href="#"o zaman jquery seçicisini daha spesifik, örneğin olabilir$('a[href!="#"]')
cjk

13

Bu eski bir soru ve buradaki çözümlerin çoğu javascript kullanıyor. O zamandan beri iOS 11.3 piyasaya sürüldü ve artık kapsam üyesini kullanabilirsiniz . Kapsam üyesi, "/"bu kapsam altındaki tüm yolların yeni bir sayfa açmayacağı bir URL'dir .

Kapsam üyesi, bu web uygulamasının uygulama bağlamının gezinme kapsamını temsil eden bir dizedir.

İşte benim örnek:

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

Bununla ilgili daha fazla bilgiyi buradan edinebilirsiniz . Bu işlevi sağlayacak jeneratörü kullanmanızı da tavsiye ederim .

Kapsamı belirtirseniz, her şey Android'e benzer şekilde çalışır, kapsam dışı hedefler Safari'de açılır - PWA'nıza geri düğmesi (durum çubuğundaki küçük).


7
Ne yazık ki, diğer web sitelerini (başka bir alandaki OAuth girişleri gibi) kapsama dahil edebileceğinize inanmıyorum.
bhollis

Hey @Amir, Angular kullanarak bir pwa oluşturdum ve Android'de, manfest.json'umu doğru bir şekilde okuyor gibi göründüğü için 'Ana ekrana ekle istemini' aldım. Ancak, IOs Chrome / Safari'de istem yok ... herhangi bir fikir?
ustad

5

Davids cevabı ve Richards yorumuna dayanarak bir alan adı kontrolü yapmalısınız. Aksi takdirde, web uygulamanızda diğer web sitelerine bağlantılar da açılır.

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

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

Yukarıdaki çözümlere iyi bir katkı. Kullanıcıların uygulamadaki harici siteleri açmasını önlemek için bir alan adı kontrolüne ihtiyaç duyuldu. Ayrıca, iOS 5 üzerinde çalışır
Ian

benim için de iOS 5 üzerinde çalışıyor. Sorun bazen önbellekte olabilir. Farklı yaklaşımları test ederken iOS'u önbelleğini geçersiz kılmaya ve JS dosyalarının yeni sürümünü almaya zorlayamadım (Safari değişiklikleri aldı, ancak Ana Ekrana uygulama ekledikten sonra artık yok). Geliştirici sunucumun bağlantı noktasını değiştirmek yardımcı oldu. Maks. Yaş = 0 ayarlı (veya eşdeğeri) varsa, bu muhtemelen sizi etkilemez.
Lukasz Korzybski

5

JQuery Mobile kullanıyorsanız, data-ajax = 'false' özelliğini kullanırken yeni pencereyle karşılaşacaksınız. Aslında, ajaxEnabled kapalı ve harici bağlantı, $ .mobile.ajaxEnabled ayarıyla veya target = '' özniteliğine sahip olduğunda bu gerçekleşir.

Bunu kullanarak düzeltebilirsiniz:

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

(Canlı () yöntemi için Richard Poole sayesinde - bind () ile çalışmıyordu)

AjaxEnabled'ı dünya genelinde kapattıysanız, [data-ajax = 'false'] öğesini bırakmanız gerekir.

Bu, aslında jQuery Mobile'a özgü bir sorun olmasını beklediğimden çok uzun sürdü, aslında yeni pencereyi engelleyen Ajax bağlantısıydı.


Mükemmel, beni kurtardın :)
saulob

3

Bu kod iOS 5 için çalışıyor (benim için çalıştı):

Kafa etiketinde:

<script type="text/javascript">
    function OpenLink(theLink){
        window.location.href = theLink.href;
    }
</script>

Aynı pencerede açılmasını istediğiniz bağlantıda:

<a href="(your website here)" onclick="OpenLink(this); return false"> Link </a>

Bu koddan bu yorumu aldım: iphone web uygulaması meta etiketleri


Nedense bunun anlaşılması en kolay yol olduğunu düşünüyorum.
Jerrybibo

3

Belki de hedef açıkça "_blank" olarak ayarlandığında bağlantıları yeni pencerede açmaya izin vermelisiniz:

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

    // prevent internal links (href.indexOf...) to open in safari if target
    // is not explicitly set_blank, doesn't break href="#" links
    if (href.indexOf(location.hostname) > -1 && href != "#" && $(this).attr("target") != "_blank")
    {
        event.preventDefault();
        window.location = href;
    }

});

Çok teşekkürler! Twitter Bootstrap ile iOS5 için çalışan tek kod budur. Yine de üretim üzerinde çalışmaz.
Chim Kan

Mmm neden üretimde işe yaramayacağından emin değilim ama bence başka bir şey. Bana bildirin!
daformat


2

Ayrıca bağlantıyı neredeyse normal olarak da yapabilirsiniz:

<a href="#" onclick="window.location='URL_TO_GO';">TEXT OF THE LINK</a>

Ve hash etiketini ve href'i kaldırabilirsiniz, yaptığı her şey görünümü etkiler.


2

Benim için iOS 6'da işe yarayan şey buydu (rmarscher'in cevabının çok küçük bir uyarlaması):

<script>                                                                
    (function(document,navigator,standalone) {                          
        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;                         
                }                                                       
                if ("href" in curnode && (curnode.href.indexOf("http") || ~curnode.href.indexOf(location.host)) && curnode.target == false) {
                    e.preventDefault();                                 
                    location.href=curnode.href                          
                }                                                       
            },false);                                                   
        }                                                               
    })(document,window.navigator,"standalone")                          
</script>

2

Bu Sean'ın biraz uyarlanmış versiyonu ve geri düğmesini önlüyor

// this function makes anchor tags work properly on an iphone

$(document).ready(function(){
if (("standalone" in window.navigator) && window.navigator.standalone) {
  // For iOS Apps
  $("a").on("click", function(e){

    var new_location = $(this).attr("href");
    if (new_location != undefined && new_location.substr(0, 1) != "#" && new_location!='' && $(this).attr("data-method") == undefined){
      e.preventDefault();
      window.location = new_location;
    }
  });
}

});


1

Twitter Bootstrap ve Rails 3 olanlar için

$('a').live('click', function (event) {
  if(!($(this).attr('data-method')=='delete')){
    var href = $(this).attr("href");
    event.preventDefault();
    window.location = href; 
  }   
});

Silme bağlantıları hala bu şekilde çalışıyor.


1

Ben hedef = "_ blank" olanlar dışında, bağımsız web uygulaması modu içindeki tüm bağlantıları açmayı tercih ederim. Elbette jQuery kullanmak.

$(document).on('click', 'a', function(e) {
    if ($(this).attr('target') !== '_blank') {
        e.preventDefault();
        window.location = $(this).attr('href');
    }
});

1

Bir iOS web uygulaması için kullandığım bir çözüm, tüm bağlantıları (CSS tarafından düğmeler olan) form gönderme düğmelerini yaptığımdı. Bu yüzden hedef bağlantıya gönderilen bir form açtım, sonra input type = "send" En iyi yol değil, ama bu sayfayı bulmadan önce anladığım şey buydu.



1

Kullananlar için JQuery Mobile, yukarıdaki çözümler açılır iletişim kutusunu kırıyor. Bu, bağlantıları web uygulamasında tutar ve pop-up'lara izin verir.

$(document).on('click','a', function (event) {
    if($(this).attr('href').indexOf('#') == 0) {
        return true;
    }
    event.preventDefault();
    window.location = $(this).attr('href');     
});

Bunu da yapabilir:

$(document).on('click','a', function (event){
    if($(this).attr('data-rel') == 'popup'){
        return true;
    }
    event.preventDefault();
    window.location = $(this).attr('href');     
});

0

Bir sayfadaki tüm bağlantılar için kullanacağım şey ...

document.body.addEventListener(function(event) {
    if (event.target.href && event.target.target != "_blank") {
        event.preventDefault();
        window.location = this.href;                
    }
});

JQuery veya Zepto kullanıyorsanız ...

$("body").on("click", "a", function(event) {
   event.target.target != "_blank" && (window.location = event.target.href);
});

-3

Bu meta etiketi kaldırabilirsiniz.

<meta name="apple-mobile-web-app-capable" content="yes">
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.