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.