您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Enhance your AliExpress shopping experience by converting marketing links into direct product links, ensuring each product is easily accessible with a single click.
当前为
// ==UserScript== // @name AliExpress Product Link Fixer // @namespace http://tampermonkey.net/ // @version 2.1 // @license MIT // @description Enhance your AliExpress shopping experience by converting marketing links into direct product links, ensuring each product is easily accessible with a single click. // @author NewsGuyTor // @match https://*.aliexpress.com/* // @icon https://www.aliexpress.com/favicon.ico // @grant none // ==/UserScript== (function() { 'use strict'; // Initialize the MutationObserver let observer; // Main function to fix links function fixLinks() { // Temporarily disconnect the observer to prevent infinite loops if (observer) observer.disconnect(); try { removeMarketingAnchors(); rewriteAnchorsWithProductIds(); fixOrCreateLinksForDataProducts(); } catch (err) { console.error("[AliExpress Product Link Fixer v2] Error in fixLinks():", err); } // Reconnect the observer after making changes if (observer) observer.observe(document.body, { childList: true, subtree: true }); } /** * A) Remove "marketing" anchors that have /gcp/ or /ssr/ without ?productIds=... * Then unwrap them to expose individual product blocks */ function removeMarketingAnchors() { const anchors = document.querySelectorAll('a[href*="/gcp/"]:not([data-alifix-done]), a[href*="/ssr/"]:not([data-alifix-done])'); anchors.forEach(a => { if (a.dataset.alifixDone) return; // Skip already processed anchors const url = new URL(a.href); if (!url.searchParams.has('productIds')) { // Mark the anchor as processed a.dataset.alifixDone = "1"; // Remove the anchor but keep its children in the DOM unwrapAnchor(a); } }); } /** * B) Rewrite anchors that contain ?productIds=... to direct product pages */ function rewriteAnchorsWithProductIds() { const anchors = document.querySelectorAll('a[href*="/gcp/"]:not([data-alifix-done]), a[href*="/ssr/"]:not([data-alifix-done])'); anchors.forEach(a => { if (a.dataset.alifixDone) return; // Skip already processed anchors const url = new URL(a.href); const pid = url.searchParams.get('productIds'); if (pid) { a.href = `https://${url.host}/item/${pid.split(':')[0]}.html`; a.dataset.alifixDone = "1"; // Mark as processed } }); } /** * C) Ensure each <div data-product-ids="..."> has a clickable link * Either by fixing existing anchors or creating new ones */ function fixOrCreateLinksForDataProducts() { const divs = document.querySelectorAll('[data-product-ids]:not([data-alifix-done])'); divs.forEach(div => { // Mark the div as processed div.dataset.alifixDone = "1"; const pid = div.dataset.productIds; if (!pid) return; // Check if there's already an <a> inside the div const existingAnchor = div.querySelector('a[href]'); if (existingAnchor) { if (!existingAnchor.dataset.alifixDone) { existingAnchor.href = `https://${location.host}/item/${pid}.html`; existingAnchor.dataset.alifixDone = "1"; // Mark as processed } } else { // No anchor found, create one around the div const link = document.createElement('a'); link.href = `https://${location.host}/item/${pid}.html`; link.dataset.alifixDone = "1"; // Optionally, style the link to display as block to ensure full area is clickable link.style.display = "block"; // Insert the link before the div div.parentNode.insertBefore(link, div); // Move the div inside the new link link.appendChild(div); } }); } /** * Helper function to unwrap an anchor tag but keep its child elements * @param {HTMLElement} anchor - The anchor element to unwrap */ function unwrapAnchor(anchor) { const parent = anchor.parentNode; if (!parent) return; while (anchor.firstChild) { parent.insertBefore(anchor.firstChild, anchor); } parent.removeChild(anchor); } // Initial execution on page load fixLinks(); // Set up the MutationObserver to watch for dynamic content changes observer = new MutationObserver(fixLinks); observer.observe(document.body, { childList: true, subtree: true }); })();