You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Safari独立应用外部导航异常及内部导航代码问询

解析iOS独立Web应用内部导航的修复代码

Hey there, let's break down this handy snippet that fixes that frustrating issue where links in your iOS standalone web app keep popping open in Safari instead of staying inside the app itself. First, let's start with the complete version of the code (since your snippet got cut off):

(function(document, navigator, standalone) {
    // Prevents links from opening in mobile Safari when in standalone mode
    // This script must be the first one in your <head>
    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)) && 
                !(/^javascript:/i.test(curnode.href))
            ) {
                e.preventDefault();
                location.href = curnode.href;
            }
        }, false);
    }
})(document, window.navigator, 'standalone');

What this code actually does

Let's break it down piece by piece:

  • Detect standalone mode: First, it checks for navigator.standalone — an iOS-only property that returns true when your web app is opened from the home screen (not in regular Safari). If this isn't true, the script does nothing.
  • Catch all clicks: It binds a click event listener to the entire document, so it captures every click on the page.
  • Find the actual link: When a click happens, it traverses up the DOM tree from the clicked element until it hits an <a> tag or the <html> element. This ensures we're dealing with the actual link, even if it's nested inside buttons, divs, or other elements.
  • Filter and intercept navigation:
    • It only acts on elements with an href attribute
    • It checks that the link is either an HTTP(S) link or belongs to your app's domain (so it doesn't mess with internal javascript: links or other protocols)
    • It stops the default Safari navigation behavior, then uses document.location.href to load the link inside the standalone app's web view instead.

Critical things to keep in mind

  • Load order matters: The comment says this script needs to be the first one in your <head> — this ensures the click listener is set up before any other elements or scripts load, so no early clicks slip through the cracks.
  • Same-domain restriction: By default, this only handles links to your own domain. If you want external links to open inside the app too, you can remove the ~curnode.href.indexOf(location.host) check, but note that external sites will load in the app's web view (users can still navigate back with the web view's back button).
  • Android doesn't need this: Android's progressive web apps (PWAs) handle internal navigation by default, so this script is only useful for iOS Safari standalone apps.
  • target="_blank" links: This script will force these to open internally too. If you want to keep some links opening in Safari, add a check for curnode.target !== '_blank' in the condition.

Troubleshooting common issues

  • Some links still open in Safari?: Double-check the link's href — if it's a different protocol (like mailto: or tel:), the script ignores it. If it's a dynamic link loaded after the page loads, don't worry — since we're using event delegation on the document, it should still catch it. If it's an external domain, adjust the domain check as mentioned above.
  • Script isn't working at all?: Make sure you're actually opening the app from the home screen (not in Safari). You can test by opening the app's dev tools and checking if navigator.standalone returns true.

内容的提问来源于stack exchange,提问作者Mr.Web

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:14:38