iPhone Safari Web App이 새 창에서 링크를 엽니 다


155

홈 화면에 아이콘을 추가 한 후 웹에 문제가 있습니다. 웹이 홈 화면에서 시작되면 모든 링크가 Safari의 새 창에서 열리고 전체 화면 기능이 손실됩니다. 어떻게 방지 할 수 있습니까? 나는 아무런 대답도 찾지 못했습니다. 답이없는 동일한 질문 만.


3
이제에서 scope매개 변수를 사용할 수 있습니다 manifest.json. 자세한 내용은 내 답변을 참조하십시오. iOS 11.3에서 테스트했으며 작동합니다.
Amir Raminfar

3
: 아이폰 OS 11.3 개방 사파리과 사투를 벌인 사람을 위해, 반복, 여기 AmirRaminfar의 답변을 @ 참조하십시오 stackoverflow.com/a/49604315/32055
크리스 헤인즈

답변:


110

iWebKit 프레임 워크 에서 JavaScript 솔루션을 찾았습니다 .

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
명백한 사실을 밝히고 명시 적으로 밝히기 위해 : iOS는 Web Apps의 링크를 Safari에서 열어야하는 것으로 취급하고, 자바 스크립트 위치 변경은 웹앱에서 깔끔하게 허용되는 인앱 액션으로 처리합니다. 위의 코드는 기본 링크 동작을 방해하여 js 탐색 호출로 대체하기 때문에 작동합니다.
Oskar Austegard 13:15

6
반대의 예가 있습니까? iPhone 웹 앱이 Safari 이벤트에서 페이지를 열도록 강요하지만 JavaScript 위치가 변경 되었습니까?
tkahn

1
@Pavel iwebkit을 언급 해 주셔서 감사합니다 :). D : 어떤 트래픽을 얻을하는 데 도움이
cmplieger

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

1
부작용이 있습니까?
pingu

94

여기에있는 다른 솔루션은 외부 링크 (Safari에서 외부 적으로 열려고 함)를 고려하지 않거나 상대 링크 (도메인이없는)를 고려하지 않습니다.

html5 mobile-boilerplate 프로젝트는이 요점에 연결되어 있으며 https://gist.github.com/1042026

그들이 작성한 최종 코드는 다음과 같습니다.

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

이는 회사의 "문의하기"페이지 인 한 페이지를 제외하고는 효과적입니다. 페이지를 표시하는 대신 "지도"응용 프로그램을 열고 사무실을 찾아냅니다. 이 문제의 원인은 무엇이며 어떻게 해결할 수 있습니까?
Jonathan

@Jonathan 확실하지 않습니다. 이 스크립트를 제거해도 발생하지 않습니까? 사이트에 대한 링크를 게시 하시겠습니까? 아니면 더 나은 새로운 질문을여십시오.
rmarscher

@rmarscher 이것은 제공 한 코드를 실행할 때만 발생합니다. 나는 웹 개발자 자신이며 왜 이런 식으로 링크를 처리하는지 이해할 수 없습니다. 현재 코드를 실행하고 있지 않으므로 페이지 URL이 없으므로 눈에 띄지 않습니다. 또한 독립 실행 형뿐만 아니라 일반 Safari에도 영향을 미칩니다. 답변 주셔서 감사합니다!
Jonathan

이것은 받아 들일만한 대답이어야하며 PHPRunner로 만든 iPad1 전체 화면 클라이언트에서 코드를 헤더에 배치하여 매력을 발휘했습니다. 왜 많은 BW 오버 헤드없이 읽을 수있는 간결한 코드 비트처럼 보이지만 왜 그렇게 난독 화되었는지 잘 모르겠습니다 ...하지만 까다 롭고 일반적으로 정말로 감사하고 싶습니다.
sradforth

4
이것은 js 함수가 사용하는 href = "#"링크와 같은 Bootstrappy 항목을 중단시킵니다.
Sean

47

jQuery를 사용하는 경우 다음을 수행 할 수 있습니다.

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

1
.live ()가 더 좋은 이유를 설명해주세요.
ajcw

8
live는 이벤트를 아직 존재하지 않는 링크를 포함하여 모든 링크에 바인딩합니다. click는 현재 존재하는 링크에만 바인딩합니다
msaspence

감사! 생명의 은인. 방금 사파리가 왜 항상로드되는지 알아 내려고 몇 시간을 보냈습니다.
Steve

1
+1- this.hrefjQuery 객체로 캐스팅 하는 대신 사용 되었지만이 답변에 감사드립니다. iOS6에서 작동합니다.
Fenton

17
.live ()는 jQuery 1.7 에서 사용되지 않으며 1.9에서 제거되었습니다 . 대신 $ (document) .on ( 'click', 'a', function () {...})을 사용하십시오.
Tom Davies

21

이것은 iOS 6.1 및 Bootstrap JS 링크 (예 : 드롭 다운 메뉴 등)에서 작동합니다.

$(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. 실제로 링크를 수정하기 전에 웹 응용 프로그램을 사용하고 있는지 확인합니다.
트롤리

1
iOS 8.0.2에서 작동합니다! 감사합니다
Joel Murphy

1
@sean 이미지 맵을 href로 사용하는 iPad에서 다른 웹 응용 프로그램을 실행 중이며이 코드가 작동하지 않습니다. 다른 모든 링크에서 잘 작동합니다. 이 코드를 이미지 맵과 함께 작동시키는 방법에 대한 아이디어가 있습니까? 전체 청크를 복사하고 $('a').on('click', function (e) {`, function (e) {`으로 바꾸려고 시도했지만 $('area').on('click'작동하지 않는 것 같습니다. 어떤 아이디어?
선충

이미 클릭 기능이 정의되어 a있는 href="#"경우 jquery 선택기에 대해 더 구체적으로 지정할 수 있습니다. 예$('a[href!="#"]')
cjk

13

이것은 오래된 질문이며 여기에있는 많은 솔루션이 자바 스크립트를 사용하고 있습니다. 그 이후로 iOS 11.3이 출시되었으며 이제 scope 멤버를 사용할 수 있습니다 . 범위 멤버는 "/"해당 범위 아래의 모든 경로가 새 페이지를 열지 않는 URL 입니다.

범위 멤버는이 웹 응용 프로그램 응용 프로그램 컨텍스트의 탐색 범위를 나타내는 문자열입니다.

내 예는 다음과 같습니다.

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

자세한 내용은 여기를 참조 하십시오 . 또한 이 기능을 제공 할 생성기 를 사용하는 것이 좋습니다 .

범위를 지정하면 모든 것이 Android와 유사하게 예상대로 작동하며 범위를 벗어난 대상은 Safari에서 열릴 수 있습니다 (상태 표시 줄의 작은 항목).


7
불행히도 다른 웹 사이트 (예 : 다른 도메인의 OAuth 로그인)를 범위에 포함시킬 수 있다고 생각하지 않습니다.
bhollis

안녕하세요 @Amir, Angular를 사용하여 pwa를 만들었고 Android에서는 'manfest.json을 올바르게 읽는 것처럼'홈 화면에 추가 프롬프트 '가 나타납니다. 그러나 IOs Chrome / Safari에서는 프롬프트가 ... 아이디어가 없습니까?
ustad

5

Davids 답변 및 Richards 의견에 따라 도메인 확인을 수행해야합니다. 그렇지 않으면 다른 웹 사이트에 대한 링크도 웹 응용 프로그램에 열립니다.

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

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

위의 솔루션에 추가하십시오. 사람들이 앱에서 외부 사이트를 열지 못하도록 도메인 확인이 필요했습니다. 또한 iOS 5에서 작동합니다.
Ian

iOS 5에서도 작동합니다. 때때로 캐시에 문제가있을 수 있습니다. 다른 접근 방식을 테스트하는 동안 iOS가 캐시를 무효화하고 새로운 버전의 JS 파일을 검색하도록 강요 할 수 없었습니다 (Safari는 변경 사항을 선택했지만 더 이상 홈 화면에 앱을 추가 한 후). 내 개발 서버의 포트를 변경하는 데 도움이되었습니다. max-age = 0 또는 이와 동등한 값을 설정하면 영향을 미치지 않습니다.
Lukasz Korzybski

5

jQuery Mobile을 사용하는 경우 data-ajax = 'false'속성을 사용할 때 새 창이 나타납니다. 실제로, 이것은 $ .mobile.ajaxEnabled 설정에 의해 또는 target = ''속성에 의해 ajaxEnabled가 꺼지고 외부 링크에 의해 또는 외부 링크에 의해 발생할 때마다 발생합니다.

이것을 사용하여 고칠 수 있습니다.

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

(live () 메소드에 대해 Richard Poole에게 감사합니다-bind ()와 함께 작동하지 않았습니다)

전역 적으로 ajaxEnabled를 끈 경우 [data-ajax = 'false']를 삭제해야합니다.

실제로 새 창을 금지하는 Ajax 연결 인 jQuery Mobile 관련 문제가 될 것으로 예상했기 때문에 다소 오래 걸렸습니다.


완벽, 당신은 저를 저장 :)
saulob

3

이 코드는 iOS 5에서 작동합니다.

헤드 태그에서 :

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

같은 창에서 열려고하는 링크에서 :

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

이 주석 에서이 코드를 얻었습니다 : iphone web app meta tags


어떤 이유로 나는 이것이 가장 이해하기 쉽다고 생각합니다.
Jerrybibo

3

target이 명시 적으로 "_blank"로 설정된 경우 새 창에서 링크를 열도록 허용해야 할 수도 있습니다.

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

});

고마워요! 이것은 트위터 부트 스트랩이있는 iOS5에서 작동하는 유일한 코드입니다. 그러나 프로덕션에서는 작동하지 않습니다.
Chim Kan

왜 그것이 프로덕션에서 작동하지 않을지는 모르겠지만 다른 것 같습니다. 알려주세요!
daformat


2

거의 정상적으로 연결하는 것도 가능합니다 :

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

또한 해시 태그와 href를 제거하여 모양에 영향을 미치는 모든 것을 제거 할 수 있습니다.


2

이것은 iOS 6에서 나를 위해 일한 것입니다 (rmarscher의 답변에 대한 약간의 적응).

<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

이것은 뒤로 버튼을 막는 Sean의 약간 적응 된 버전입니다.

// 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 및 Rails 3 사용자

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

삭제 링크는 여전히 이런 식으로 작동합니다.


1

target = "_ blank"가있는 링크를 제외한 독립형 웹앱 모드 내에서 모든 링크를 여는 것을 선호합니다. 물론 jQuery를 사용합니다.

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

1

iOS 웹 앱에 사용 된 한 가지 해결 방법은 모든 링크 (CSS의 버튼)를 제출 버튼으로 만들었습니다. 그래서 대상 링크에 게시 된 양식을 연 다음 type = "submit"을 입력하십시오. 가장 좋은 방법은 아니지만이 페이지를 발견하기 전에 알아 낸 것입니다.



1

를 사용 JQuery Mobile하는 경우 위의 솔루션이 팝업 대화 상자를 중단합니다. 그러면 webapp 내에 링크가 유지되고 팝업이 허용됩니다.

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

또한 다음과 같이 할 수 있습니다.

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

0

다음은 페이지의 모든 링크에 사용하는 것입니다 ...

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

jQuery 또는 Zepto를 사용하는 경우 ...

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

-3

이 메타 태그를 간단히 제거 할 수 있습니다.

<meta name="apple-mobile-web-app-capable" content="yes">
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.