当页开链

全站通用型页内增强脚本

目前为 2025-02-27 提交的版本。查看 最新版本

// ==UserScript==
// @name         当页开链
// @namespace    https://gf.qytechs.cn/zh-CN/scripts/497533
// @version      3.1
// @description  全站通用型页内增强脚本
// @author       none
// @match        *://*/*
// @grant        unsafeWindow
// @grant        GM_registerMenuCommand
// @run-at       document-body
// @connect      *
// ==/UserScript==

(function() {
    'use strict';
    // 函数用于在当前标签页中打开链接
    function openLinkInCurrentTab(url) {
        window.location.href = url;
    }

    // 拦截所有点击事件
    document.addEventListener('click', function(event) {
        var target = event.target;

        // 检查点击的元素以及其父元素是否是链接
        while (target && target.tagName !== 'A') {
            target = target.parentElement;
        }

        if (target && target.tagName === 'A') {
            // 阻止默认行为,即在新标签页中打开链接
            event.preventDefault();

            // 获取链接的目标 URL
            var url = target.href;

            // 在当前标签页中打开链接
            openLinkInCurrentTab(url);
        }
    });

    // 协议安全名单(2025标准)
    const SAFE_PROTOCOLS = new Set([
        'http:', 'https:', 'ftp:',
        'mailto:', 'tel:', 'sms:'
    ]);

    // Shadow DOM处理器(支持5级嵌套)
    const processShadowRoot = (root, depth = 0) => {
        if (depth > 5) return;
        root.querySelectorAll('a, form').forEach(processElement);
        root.querySelectorAll('*').forEach(node => {
            if (node.shadowRoot) {
                processShadowRoot(node.shadowRoot, depth + 1);
            }
        });
    };

    // 增强元素处理逻辑
    const processElement = (element) => {
        // 协议过滤
        try {
            const href = element.href?.toLowerCase() || '';
            const protocol = new URL(href, location.href).protocol;
            if (!SAFE_PROTOCOLS.has(protocol)) return;
        } catch(e) {
            return;
        }

        // 多维度属性清理
        ['target', 'onclick', 'data-target'].forEach(attr => {
            element.removeAttribute(attr);
        });

        // 表单提交劫持
        if (element.matches('form') && !element.__patched) {
            element.__patched = true;
            const originalSubmit = element.submit;
            element.submit = function() {
                this.target = '_self';
                originalSubmit.call(this);
            };
        }
    };

    // 全局基础策略
    const applyBaseStrategy = () => {
        if (!document.querySelector('base')) {
            const base = document.createElement('base');
            base.target = '_self';
            document.head.prepend(base);
        }
    };

    // 优化后的智能观察器(2025最新方案)
    const initObserver = () => {
        const processedElements = new WeakSet();
        let pendingUpdates = new Set();
        let updateScheduled = false;

        const batchProcessor = () => {
            const tempSet = new Set(pendingUpdates);
            pendingUpdates.clear();

            tempSet.forEach(node => {
                if (node.nodeType === 1 && !processedElements.has(node)) {
                    // 处理主节点
                    processElement(node);
                    processedElements.add(node);

                    // 处理关联Shadow DOM
                    const processNestedShadow = (element, depth = 0) => {
                        if (depth > 5) return;
                        if (element.shadowRoot) {
                            element.shadowRoot.querySelectorAll('a').forEach(a => {
                                if (!processedElements.has(a)) {
                                    processElement(a);
                                    processedElements.add(a);
                                }
                            });
                            element.shadowRoot.querySelectorAll('*').forEach(child =>
                                processNestedShadow(child, depth + 1)
                            );
                        }
                    };
                    processNestedShadow(node);
                }
            });

            updateScheduled = false;
        };

        const observer = new MutationObserver(mutations => {
            mutations.forEach(({ addedNodes, attributeName, target }) => {
                // 收集新增节点
                addedNodes.forEach(node => {
                    if (node.nodeType === 1) {
                        pendingUpdates.add(node);
                    } else if (node.nodeType === 11) { // 处理文档片段
                        node.querySelectorAll('a').forEach(a =>
                            pendingUpdates.add(a)
                        );
                    }
                });

                // 响应属性变更
                if (attributeName === 'target' && target.tagName === 'A') {
                    pendingUpdates.add(target);
                }
            });

            // 智能调度处理
            if (!updateScheduled && pendingUpdates.size) {
                updateScheduled = true;
                if (typeof requestIdleCallback === 'function') {
                    requestIdleCallback(batchProcessor, { timeout: 50 });
                } else {
                    requestAnimationFrame(batchProcessor);
                }
            }
        });

        observer.observe(document, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['target', 'href']
        });
    };

    // 路由劫持层(支持现代框架)
    const hijackRouting = () => {
        const routerApis = [
            history.pushState,
            history.replaceState,
            unsafeWindow.router?.navigate
        ];

        routerApis.forEach(fn => {
            const original = fn;
            fn = (...args) => {
                const result = original.apply(this, args);
                setTimeout(() => {
                    document.querySelectorAll('a').forEach(processElement);
                }, requestAnimationFrame(() => 0));
                return result;
            };
        });
    };

    // 核心初始化
    const main = () => {
        if (window.self !== window.top) return;

        applyBaseStrategy();
        hijackRouting();

        // 初始处理
        document.querySelectorAll('a, form').forEach(processElement);
        processShadowRoot(document);

        // 动态处理
        initObserver();

        // 全局事件拦截
        document.addEventListener('click', e => {
            const target = e.composedPath()[0];
            if (target.matches('a')) processElement(target);
        }, { capture: true, passive: true });

        // 强化window.open处理
        unsafeWindow.open = function(url, target, ...args) {
            return window.open(url, '_self', ...args);
        };
    };

    // 启动逻辑
    if (document.readyState === 'complete') {
        main();
    } else {
        document.addEventListener('DOMContentLoaded', main);
    }

    // 调试功能
    GM_registerMenuCommand('强制刷新处理', () => {
        document.querySelectorAll('a, form').forEach(processElement);
        processShadowRoot(document);
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址