/* ============================================================ host-nav.js · 小程序里换页开「容器页」(2026-11-09 用户) ------------------------------------------------------------ 「在任何一个子页面点小程序『复制链接』,打开应该进到那个子页面,现在都进首页」—— 「复制链接」复制的是**小程序当前页面**的路径和参数。首页壳里 location.href 换页,小程序页面一直是首页壳, 复制出来永远是首页。所以在小程序里进子页面 / 应用 / 广场笔记时,navigateTo 通用容器 pages/annex/web_view/index?url=<净地址>(分享卡片落地用的同一个页,容器按打开者自己的身份注入), 小程序当前页就是那一页。 MBHost.open(url, fallback) 小程序里开容器页;不在小程序 → false(调用方照旧 location.href); navigateTo 失败(页面栈满 10 层等)→ 调 fallback,没给就 location.href = url MBHost.back(fallback) 本页是 open() 开出来的容器页(地址带 _hv=1)→ navigateBack 回上一页,返回 true; 后退失败(复制链接直接打开、没有上一页)→ 调 fallback MBHost.home(fallback) 同上条件 → switchTab 回小程序首页(首页壳是 tabBar 页,原来停的位置还在) ⚠️ url 只放净地址:去掉 openid/unionid/__no_identity/return_url 和 hash 里的身份,复制出去不带分享人身份。 ⚠️ 加 _hv=1 只为让页面知道「我在容器页里」,返回时用 navigateBack,不用在容器里再开一个首页。 ============================================================ */ (function (g) { 'use strict'; if (g.MBHost) return; var VIEW = '/pages/annex/web_view/index'; var at = 0; function mp() { return g.wx && g.wx.miniProgram; } function inMp() { return g.__wxjs_environment === 'miniprogram' || /miniProgram/i.test(navigator.userAgent); } function inView() { return /[?&]_hv=1(&|$)/.test(location.search); } function clean(url) { var u = new URL(url, location.href); ['openid', 'unionid', '__no_identity', 'return_url', 'norestore'].forEach(function (k) { u.searchParams.delete(k); }); if (/(^|[#&])(openid|unionid|phone|nickname|avatar|norestore)=/.test(u.hash)) u.hash = ''; u.searchParams.set('_hv', '1'); return u.href; } var H = { inMp: inMp, inView: inView, open: function (url, fallback) { var m = mp(); if (!inMp() || !m || typeof m.navigateTo !== 'function') return false; if (Date.now() - at < 1000) return true; // 连点:上一次 navigateTo 还在路上 var c; try { c = clean(url); } catch (e) { return false; } at = Date.now(); m.navigateTo({ url: VIEW + '?url=' + encodeURIComponent(c), fail: function () { at = 0; if (fallback) fallback(); else location.href = url; } }); return true; }, back: function (fallback) { var m = mp(); if (!inView() || !inMp() || !m || typeof m.navigateBack !== 'function') return false; m.navigateBack({ delta: 1, fail: function () { if (fallback) fallback(); } }); return true; }, home: function (fallback) { var m = mp(); if (!inView() || !inMp() || !m || typeof m.switchTab !== 'function') return false; m.switchTab({ url: '/pages/index/index', fail: function () { if (fallback) fallback(); } }); return true; } }; g.MBHost = H; /* 页面里的 指向本站别的页面:小程序里也开容器页(别人已经 preventDefault 的不管) */ document.addEventListener('click', function (e) { if (e.defaultPrevented || e.button || e.metaKey || e.ctrlKey || !inMp()) return; var a = e.target && e.target.closest && e.target.closest('a[href]'); if (!a || a.target || a.hasAttribute('download')) return; var href = a.getAttribute('href') || ''; if (!href || href.charAt(0) === '#' || /^(javascript|mailto|tel):/i.test(href)) return; var u; try { u = new URL(href, location.href); } catch (err) { return; } if (u.origin !== location.origin || u.pathname === location.pathname) return; if (H.open(u.href)) e.preventDefault(); }); })(window);