新增跳转时打开新窗口功能

This commit is contained in:
2026-07-24 18:19:33 +08:00
parent 0e88255852
commit f3bdb07e3d
22 changed files with 132 additions and 46 deletions
+83
View File
@@ -33,3 +33,86 @@ window.CURRENT_ENV = (function () {
// 获取当前环境配置
window.CURRENT_CONFIG = window.ENV[window.CURRENT_ENV];
window.NavigationUtil = (function (window, document) {
const blockedProtocols = /^(?:javascript|data|vbscript|mailto|tel):/i;
function shouldOpenInNewTab(anchor) {
const href = (anchor.getAttribute('href') || '').trim();
return href && href !== '#' && !href.startsWith('#') &&
!anchor.hasAttribute('download') && !blockedProtocols.test(href);
}
function prepareAnchor(anchor) {
if (!anchor || anchor.tagName !== 'A' || !shouldOpenInNewTab(anchor)) {
return;
}
if (anchor.target !== '_blank') {
anchor.target = '_blank';
}
const relTokens = (anchor.getAttribute('rel') || '').split(/\s+/).filter(Boolean);
if (!relTokens.includes('noopener')) {
anchor.setAttribute('rel', [...relTokens, 'noopener'].join(' '));
}
}
function prepareAnchors(root) {
if (root.nodeType === 1 && root.matches('a[href]')) {
prepareAnchor(root);
}
root.querySelectorAll('a[href]').forEach(prepareAnchor);
}
function installLinkTargeting() {
prepareAnchors(document);
new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes') {
prepareAnchor(mutation.target);
return;
}
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1) {
prepareAnchors(node);
}
});
});
}).observe(document.documentElement, {
subtree: true,
childList: true,
attributes: true,
attributeFilter: ['href', 'target', 'download']
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', installLinkTargeting, { once: true });
} else {
installLinkTargeting();
}
return {
open(url) {
const destination = String(url || '').trim();
if (!destination) {
return null;
}
const openedWindow = window.open(destination, '_blank', 'noopener');
if (openedWindow) {
openedWindow.opener = null;
}
return openedWindow;
}
};
})(window, document);
+1 -1
View File
@@ -373,7 +373,7 @@
"资料上传成功,请等待审核通过",
{ icon: 1, time: 1800 },
function () {
window.location.href = "usercenter.html";
NavigationUtil.open("usercenter.html");
}
);
} else {
+4 -4
View File
@@ -3,12 +3,12 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="../config.js"></script>
<title id="page-title">神彩算 - 免费文章收藏</title>
<script>
window.location.replace("mianfeishoucang.html?tab=free");
NavigationUtil.open("mianfeishoucang.html?tab=free");
</script>
<script src="../public/css/layui/layui.js"></script>
<script src="../config.js"></script>
<script src="../utils/ApiClient.js"></script>
<script src="../utils/DateUtil.js"></script>
<script src="../utils/CommonUtil.js"></script>
@@ -137,7 +137,7 @@
);
});
} else {
window.location.href = "login.html";
NavigationUtil.open("login.html");
return;
}
}
@@ -157,7 +157,7 @@
function loadCollections() {
const token = localStorage.getItem("token");
if (!token) {
window.location.href = "login.html";
NavigationUtil.open("login.html");
return;
}
+1 -1
View File
@@ -246,7 +246,7 @@
},
);
} else {
window.location.href = "login.html";
NavigationUtil.open("login.html");
}
}
+3 -3
View File
@@ -254,7 +254,7 @@
"您还不是实习或正式专家,暂不能发布文章。",
{ title: "暂无权限" },
function () {
window.location.href = "apply.html";
NavigationUtil.open("apply.html");
},
);
return;
@@ -284,7 +284,7 @@
});
return;
}
window.location.href = targetHref;
NavigationUtil.open(targetHref);
});
});
});
@@ -525,7 +525,7 @@
"发布成功,请等待审核",
{ icon: 1, time: 1600 },
function () {
window.location.href = "index.html";
NavigationUtil.open("index.html");
},
);
} else {
+1 -1
View File
@@ -217,7 +217,7 @@
function logout() {
localStorage.removeItem("token");
window.location.href = "login.html";
NavigationUtil.open("login.html");
}
function renderLoginState() {
+3 -3
View File
@@ -210,7 +210,7 @@
{ btn: ["去登录", "取消"] },
function (index) {
layui.layer.close(index);
window.location.href = "login.html";
NavigationUtil.open("login.html");
},
);
});
@@ -566,11 +566,11 @@
ApiClient.post(ApiClient.API.authLogout, {})
.then(function () {
localStorage.removeItem("token");
window.location.href = "login.html";
NavigationUtil.open("login.html");
})
.catch(function () {
localStorage.removeItem("token");
window.location.href = "login.html";
NavigationUtil.open("login.html");
});
}
+1 -1
View File
@@ -316,7 +316,7 @@
}
function redirectAfterLogin() {
window.location.href = getLoginRedirectUrl();
NavigationUtil.open(getLoginRedirectUrl());
}
function bindReferralThenRedirect() {
+3 -3
View File
@@ -497,7 +497,7 @@
{ icon: 3, title: "提示" },
function (index) {
layui.layer.close(index);
window.location.href = "login.html";
NavigationUtil.open("login.html");
},
);
return;
@@ -533,7 +533,7 @@
{ icon: 3, title: "提示" },
function (index) {
layui.layer.close(index);
window.location.href = "login.html";
NavigationUtil.open("login.html");
},
);
return;
@@ -671,7 +671,7 @@
{ icon: 3, title: "提示" },
function (index) {
layui.layer.close(index);
window.location.href = "login.html";
NavigationUtil.open("login.html");
},
);
return;
+1 -1
View File
@@ -223,7 +223,7 @@
function checkLogin() {
if (!CommonUtil.getAuthToken()) {
window.location.href = "login.html";
NavigationUtil.open("login.html");
return;
}
+3 -2
View File
@@ -41,6 +41,7 @@
color: #111827;
}
</style>
<script src="../config.js"></script>
</head>
<body>
<div class="box">
@@ -59,9 +60,9 @@
if (!inApp && location.search.indexOf(prefix) === 0) {
const target = location.search.slice(prefix.length);
if (target && target.charAt(0) === "/" && target.indexOf("//") !== 0) {
location.replace(target);
NavigationUtil.open(target);
}
}
</script>
</body>
</html>
</html>
+4 -3
View File
@@ -712,14 +712,15 @@
function redirectAfterRegister(hasToken) {
if (hasToken) {
window.location.href =
NavigationUtil.open(
typeof CommonUtil !== "undefined"
? CommonUtil.siteHref("/index.html")
: "index.html";
: "index.html",
);
return;
}
window.location.href = "login.html";
NavigationUtil.open("login.html");
}
function finishRegisterSuccess(res) {
+1 -1
View File
@@ -529,7 +529,7 @@
"密码重置成功,即将前往登录",
{ icon: 1, time: 1200 },
function () {
window.location.href = "login.html";
NavigationUtil.open("login.html");
},
);
return;
+2 -2
View File
@@ -176,7 +176,7 @@
function redirectHome() {
setStatus("登录成功,正在跳转...", false);
window.setTimeout(() => {
window.location.replace(homeUrl());
NavigationUtil.open(homeUrl());
}, 500);
}
@@ -238,7 +238,7 @@
clearAccountBindMode();
setStatus("微信绑定成功,正在返回个人中心...", false);
window.setTimeout(() => {
window.location.replace(returnUrl);
NavigationUtil.open(returnUrl);
}, 500);
}
+1 -1
View File
@@ -312,7 +312,7 @@
function checkLogin() {
const token = CommonUtil.getAuthToken ? CommonUtil.getAuthToken() : localStorage.getItem("token");
if (!token) {
window.location.href = "login.html";
NavigationUtil.open("login.html");
return;
}
$("#notLoggedInBox").addClass("tx-hidden");
+1 -1
View File
@@ -235,7 +235,7 @@
function checkLogin() {
const token = CommonUtil.getAuthToken ? CommonUtil.getAuthToken() : localStorage.getItem("token");
if (!token) {
window.location.href = "login.html";
NavigationUtil.open("login.html");
return;
}
$("#notLoggedInBox").addClass("tl-hidden");
+1 -1
View File
@@ -355,7 +355,7 @@
},
);
} else {
window.location.href = "login.html";
NavigationUtil.open("login.html");
}
}
+1
View File
@@ -256,6 +256,7 @@
}
}
</style>
<script src="../config.js"></script>
</head>
<body>
<main class="wrap" aria-labelledby="page-title">
+9 -9
View File
@@ -112,26 +112,26 @@
<button
class="uc-btn uc-btn-expert"
id="expertApplyBtn"
onclick="window.location.href = 'apply.html'"
onclick="NavigationUtil.open('apply.html')"
>
专家申请
</button>
<button
class="uc-btn uc-btn-publish"
id="publishArticleBtn"
onclick="window.location.href = 'fabumianfeiwenzhang.html'"
onclick="NavigationUtil.open('fabumianfeiwenzhang.html')"
>
发布文章
</button>
<button
class="uc-btn uc-btn-collection"
onclick="window.location.href = 'mianfeishoucang.html?tab=free'"
onclick="NavigationUtil.open('mianfeishoucang.html?tab=free')"
>
我的收藏
</button>
<button
class="uc-btn uc-btn-tuiguang"
onclick="window.location.href = 'tuiguang.html'"
onclick="NavigationUtil.open('tuiguang.html')"
>
分享推广
</button>
@@ -530,7 +530,7 @@
if (state.isApplying) {
$applyBtn.removeAttr("onclick");
} else {
$applyBtn.attr("onclick", "window.location.href = 'apply.html'");
$applyBtn.attr("onclick", "NavigationUtil.open('apply.html')");
}
}
@@ -695,7 +695,7 @@
{ btn: ["去登录", "取消"] },
function (index) {
layui.layer.close(index);
window.location.href = "login.html";
NavigationUtil.open("login.html");
},
);
});
@@ -757,7 +757,7 @@
});
localStorage.removeItem("token");
setTimeout(function () {
window.location.href = "login.html";
NavigationUtil.open("login.html");
}, 1500);
},
);
@@ -812,11 +812,11 @@
ApiClient.post(ApiClient.API.authLogout, null, { headers: CommonUtil.authHeaders() })
.then(function (res) {
localStorage.removeItem("token");
window.location.href = "login.html";
NavigationUtil.open("login.html");
})
.catch(function () {
localStorage.removeItem("token");
window.location.href = "login.html";
NavigationUtil.open("login.html");
});
}
+2 -2
View File
@@ -22,7 +22,7 @@ const $ = layui.$;
title: "暂无权限",
},
function () {
window.location.href = "fabumianfeiwenzhang.html";
NavigationUtil.open("fabumianfeiwenzhang.html");
},
);
return;
@@ -754,7 +754,7 @@ const $ = layui.$;
throw new Error(res.msg || "发布失败");
}
layer.msg("发布成功", { icon: 1, time: 1200 }, function () {
window.location.href = "usercenter.html";
NavigationUtil.open("usercenter.html");
});
})
.catch(function (error) {
+3 -3
View File
@@ -173,7 +173,7 @@ const ApiClient = {
if (!response.ok) {
if (response.status === 401) {
localStorage.removeItem('token');
window.location.href = 'login.html';
NavigationUtil.open('login.html');
}
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
@@ -331,10 +331,10 @@ const ApiClient = {
if (/\/(login|reg|repwd)\.html$/i.test(path)) return;
const returnUrl = window.location.pathname + window.location.search;
const loginPath = '/login.html?redirect=' + encodeURIComponent(returnUrl);
window.location.href =
NavigationUtil.open(
typeof CommonUtil !== 'undefined' && CommonUtil.siteHref
? CommonUtil.siteHref(loginPath)
: ((window.CURRENT_ENV === 'development' ? '/html/login.html?redirect=' : '/login.html?redirect=') + encodeURIComponent(returnUrl));
: ((window.CURRENT_ENV === 'development' ? '/html/login.html?redirect=' : '/login.html?redirect=') + encodeURIComponent(returnUrl)));
},
buildUrl(url, params) {
+3 -3
View File
@@ -110,7 +110,7 @@ const CommonUtil = {
{ btn: ['去登录', '取消'] },
function (index) {
layui.layer.close(index);
window.location.href = 'login.html';
NavigationUtil.open('login.html');
}
);
});
@@ -1178,7 +1178,7 @@ const CommonUtil = {
}
const authUrl = this.extractWechatAuthUrl(res);
if (!authUrl) throw new Error('后端未返回微信授权地址');
window.location.href = authUrl;
NavigationUtil.open(authUrl);
})
.catch((error) => {
const message = error.message || '微信登录暂不可用,请稍后再试';
@@ -1325,7 +1325,7 @@ const CommonUtil = {
}
const authUrl = this.extractWechatAuthUrl(res);
if (!authUrl) throw new Error('后端未返回微信授权地址');
window.location.href = authUrl;
NavigationUtil.open(authUrl);
})
.catch((error) => {
const message = error.message || '微信绑定暂不可用,请稍后再试';