Greasy Fork

Greasy Fork is available in English.

精简链接的跟踪代码

自用的链接精简

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         精简链接的跟踪代码
// @version      1.1
// @description  自用的链接精简
// @author       jkfujr
// @include      *.taobao.com/*
// @include      *.tmall.com/*
// @include      *.tmall.hk/*
// @include      *.goofish.com/*
// @include      *www.baidu.com/*
// @license      GNU GPLv3
// @namespace none
// ==/UserScript==

(function() {
    'use strict';

    /**
     * 获取URL中的指定参数值
     * @param {string} name 参数名
     * @param {string} url URL字符串,默认为当前页面URL
     * @return {string|null} 参数值,没有则返回null
     */
    function getQueryString(name, url) {
        url = url || window.location.search;
        var search = url.indexOf('?') > -1 ? url.substring(url.indexOf('?') + 1) : '';
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        var r = search.match(reg);
        if (r != null) return r[2];
        return null;
    }

    /**
     * 保留URL中指定的参数,移除其他参数
     * @param {string} url 原始URL
     * @param {Array<string>} paramsToKeep 要保留的参数名数组
     * @return {string} 处理后的URL
     */
    function keepOnlyParams(url, paramsToKeep) {
        var urlObj = new URL(url);
        var baseUrl = urlObj.origin + urlObj.pathname;
        var params = new URLSearchParams();
        
        // 只保留指定的参数
        for (var i = 0; i < paramsToKeep.length; i++) {
            var paramName = paramsToKeep[i];
            var paramValue = getQueryString(paramName, urlObj.search);
            if (paramValue) {
                params.append(paramName, paramValue);
            }
        }
        
        var queryString = params.toString();
        return queryString ? baseUrl + '?' + queryString : baseUrl;
    }



    // 站点处理器对象
    var siteHandlers = {
        // 通用商品详情页处理
        'item.taobao.com': function(url) {
            return keepOnlyParams(url, ['id', 'skuId']);
        },

        'detail.tmall.com': function(url) {
            return keepOnlyParams(url, ['id', 'skuId']);
        },

        'detail.tmall.hk': function(url) {
            return keepOnlyParams(url, ['id', 'skuId']);
        },

        // 淘宝订单页面
        'buyertrade.taobao.com': function(url) {
            return keepOnlyParams(url, ['route_to']);
        },

        // 天猫页面处理
        'tmall.com': function(url) {
            var urlObj = new URL(url);
            var site = url.match(/^http(s)?:\/\/[^?]*/);
            
            if ((urlObj.hostname === "www.tmall.com" || urlObj.hostname === "tmall.com") && 
                (urlObj.pathname === "/" || urlObj.pathname === "")) {
                return site[0];
            }
            // 天猫店铺页面
            else if (urlObj.hostname.endsWith("tmall.com") && urlObj.hostname !== "www.tmall.com" && 
                (urlObj.pathname === "/" || urlObj.pathname === "")) {
                return urlObj.protocol + "//" + urlObj.hostname;
            }
            return url;
        },



        // 闲鱼商品页面处理
        'www.goofish.com': function(url) {
            var urlObj = new URL(url);
            if (urlObj.pathname === '/item') {
                return keepOnlyParams(url, ['id']);
            }
            return url;
        },

        // 百度搜索页面处理
        'www.baidu.com': function(url) {
            var urlObj = new URL(url);
            var site = url.match(/^http(s)?:\/\/[^?]*/);
            var paramValue = getQueryString("wd", urlObj.search);
            
            if (paramValue) {
                return site[0] + "?wd=" + paramValue;
            } else {
                paramValue = getQueryString("q", urlObj.search);
                if (paramValue) {
                    return site[0] + "?q=" + paramValue;
                }
            }
            return url;
        }

    };

    /**
     * 清理URL,移除不必要的参数
     * @param {string} url 需要清理的URL
     * @return {string} 清理后的URL
     */
    function cleanUrl(url) {
        try {
            var urlObj = new URL(url);
            var hostname = urlObj.hostname;
            var pureUrl = url;
            var matched = false;
            
            // 先尝试精确匹配子域名
            for (var siteDomain in siteHandlers) {
                if (siteDomain !== 'taobao.com' && hostname.includes(siteDomain)) {
                    pureUrl = siteHandlers[siteDomain](url);
                    matched = true;
                    break;
                }
            }

            // 对于没有匹配到特定处理器的淘宝域名,移除所有参数
            if (!matched && hostname.includes('taobao.com')) {
                var site = url.match(/^http(s)?:\/\/[^?]*/);
                pureUrl = site ? site[0] : urlObj.origin + urlObj.pathname;
            }

            return pureUrl;
        } catch (e) {
            console.error('清理URL时出错:', e);
            return url;
        }
    }

    /**
     * 处理页面上所有链接的点击事件
     */
    function handleLinkClicks() {
        document.addEventListener('click', function(event) {
            var target = event.target;
            while (target && target.tagName !== 'A') {
                target = target.parentElement;
            }
            if (!target || !target.href || target.getAttribute('data-cleaned') === 'true') {
                return;
            }
            var originalHref = target.href;
            var cleanedHref = cleanUrl(originalHref);
            if (cleanedHref !== originalHref) {
                target.href = cleanedHref;
                target.setAttribute('data-cleaned', 'true');
            }
        }, true);
    }

    /**
     * 处理表单提交事件(主要用于搜索表单)
     */
    function handleFormSubmits() {
        document.addEventListener('submit', function(event) {
            var form = event.target;
            
            // 检查是否是搜索表单
            if (form.action && (form.action.includes('search') || form.action.includes('s?'))) {
            }
        }, true);
    }

    /**
     * 使用MutationObserver监听DOM变化,清理动态添加的链接
     */
    function observeDOMChanges() {
        var config = { 
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['href']
        };

        var observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                if (mutation.type === 'childList') {
                    mutation.addedNodes.forEach(function(node) {
                        if (node.nodeType === 1) {
                            var links = node.getElementsByTagName('a');
                            for (var i = 0; i < links.length; i++) {
                                var link = links[i];
                                if (link.href && !link.getAttribute('data-cleaned')) {
                                    var cleanedHref = cleanUrl(link.href);
                                    if (cleanedHref !== link.href) {
                                        link.href = cleanedHref;
                                        link.setAttribute('data-cleaned', 'true');
                                    }
                                }
                            }
                        }
                    });
                }
                else if (mutation.type === 'attributes' && mutation.attributeName === 'href') {
                    var link = mutation.target;
                    if (link.href && !link.getAttribute('data-cleaned')) {
                        var cleanedHref = cleanUrl(link.href);
                        if (cleanedHref !== link.href) {
                            link.href = cleanedHref;
                            link.setAttribute('data-cleaned', 'true');
                        }
                    }
                }
            });
        });

        observer.observe(document.body, config);
    }

    // 清理页面URL
    function cleanCurrentPageUrl() {
        var currentUrl = window.location.href;
        var pureUrl = cleanUrl(currentUrl);
        if (currentUrl !== pureUrl) {
            history.replaceState(null, document.title, pureUrl);
        }
    }

    // 初始化
    function init() {
        cleanCurrentPageUrl();
        handleLinkClicks();
        handleFormSubmits();
        observeDOMChanges();
    }
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();