iPhone Safari Web App открывает ссылки в новом окне
У меня проблема с web после добавления значка на главный экран. Если веб-сайт запускается с главного экрана, все ссылки откроются в новом окне в Safari (и потеряют полноэкранную функциональность). Как я могу это предотвратить? Я не мог найти никакой помощи, только тот же вопрос без ответа.
20 ответов:
Я нашел решение JavaScript в iWebKit основа:
var a=document.getElementsByTagName("a"); for(var i=0;i<a.length;i++) { a[i].onclick=function() { window.location=this.getAttribute("href"); return false } }
другие решения здесь либо не учитывают внешние ссылки (которые вы, вероятно, хотите открыть внешне в 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>
Если вы используете jQuery, вы можете сделать:
$("a").click(function (event) { event.preventDefault(); window.location = $(this).attr("href"); });
это работает для меня на 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; } }); } });
основываясь на ответе Дэвидса и комментарии Ричардса, вы должны выполнить проверку домена. В противном случае ссылки на другие веб-сайты также будут открыты в вашем веб-приложении.
$('a').live('click', function (event) { var href = $(this).attr("href"); if (href.indexOf(location.hostname) > -1) { event.preventDefault(); window.location = href; } });
при использовании jQuery Mobile вы будете испытывать новое окно при использовании атрибута data-ajax= 'false'. На самом деле, это произойдет всякий раз, когда ajaxEnabled отключается, будучи и внешней ссылкой,$.мобильный.ajaxEnabled параметр или с помощью атрибута target=".
вы можете исправить это с помощью этого:
$("a[data-ajax='false']").live("click", function(event){ if (this.href) { event.preventDefault(); location.href=this.href; return false; } });
(спасибо Ричарду пулу за метод live () - не работал с bind())
Если вы отключили ajaxEnabled глобально, вам нужно будет отбросьте [data-ajax= 'false'].
это заняло у меня довольно много времени, чтобы понять, как я ожидал, что это будет проблема jQuery Mobile, где на самом деле это была ссылка Ajax, которая фактически запрещала новое окно.
Это старый вопрос, и многие из решений здесь используют javascript. С тех пор iOS 11.3 была выпущена, и теперь вы можете использовать scope member. Элемент scope-это URL-адрес типа
"/"
где все пути в этой области не будет открывать новую страницу.элемент scope-это строка, представляющая область навигации контекст приложения этого веб-приложения.
вот мой пример:
{ "name": "Test", "short_name": "Test", "lang": "en-US", "start_url": "/", "scope": "/", ... }
вы также можете прочитать больше об этом здесь. Я также рекомендую использовать генератор который обеспечит эту функциональность.
Если вы укажете область, все работает так, как ожидалось, подобно Android, пункты назначения вне сферы действия откроются в Safari - с помощью кнопка назад (маленькая в строке состояния) для вашего PWA.
этот код работает для iOS 5 (он работал для меня):
в теге head:
<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
возможно, вы должны разрешить открывать ссылки в новом окне, когда 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; } });
Я нашел тот, который очень полный и эффективный, потому что он проверяет, работает ли он только под автономным веб-приложением, работает без jQuery, а также прост, просто протестирован под iOS 8.2 :
Stay Standalone: предотвращение ссылок в автономных веб-приложениях открытие мобильного Safari
вы также можете сделать ссылку почти нормально:
<a href="#" onclick="window.location='URL_TO_GO';">TEXT OF THE LINK</a>
и вы можете удалить хэш-тег и href, все это влияет на внешний вид..
Это то, что работало для меня на 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>
это слегка адаптированная версия Шона, которая предотвращала кнопку Назад
// 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; } }); }
});
для тех, кто с 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; } });
удалить ссылки все еще работают таким образом.
Я предпочитаю открывать все ссылки в автономном режиме веб-приложения, кроме тех, которые имеют target= "_blank". Используя jQuery, конечно.
$(document).on('click', 'a', function(e) { if ($(this).attr('target') !== '_blank') { e.preventDefault(); window.location = $(this).attr('href'); } });
один обходной путь, который я использовал для веб-приложения iOS, заключался в том, что я сделал все ссылки (которые были кнопками CSS) кнопками отправки формы. Поэтому я открыл форму, которая отправлена в ссылку назначения, а затем введите тип= " отправить" Не самый лучший способ, но это то, что я понял, прежде чем нашел эту страницу.
Я создал установочный пакет bower из @rmarscher это который можно найти здесь:
http://github.com/stylr/iosweblinks
вы можете легко установить фрагмент с bower с помощью
bower install --save iosweblinks
для тех, кто использует
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'); });
вот что я использую для всех ссылок на странице...
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); });