新增跳转时打开新窗口功能
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user