maosiyuan

修改电子票姓名、生日、期满日期(主页/详情页/我的信息页不卡顿无闪烁)

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         maosiyuan
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  修改电子票姓名、生日、期满日期(主页/详情页/我的信息页不卡顿无闪烁)
// @author       You
// @match        *://*.interpark.com/*
// @match        *://*.interparkglobal.com/*
// @match        *://m.interpark.com/*
// @match        *://m.interparkglobal.com/*
// @match        *://*.nol.com/*
// @icon         https://interpark.com/favicon.ico
// @license      MIT
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    /*** 全局配置 ***/
    const OLD_NAME = "CHENG FANJIA";
    const NEW_NAME = "MAO SIYUAN";
    const NEW_BIRTHDAY = "(**1018)";
    const NEW_EXPIRE_DATE = "2035-12-01";

    const DATE_RE = /\d{4}-\d{2}-\d{2}/g;

    /*** 主页处理函数 ***/
    function replaceInHome() {
        document.querySelectorAll("div.mbs_4").forEach(el => {
            let html = el.innerHTML;
            let changed = false;

            if (html.includes(OLD_NAME)) {
                html = html.replaceAll(OLD_NAME, NEW_NAME);
                changed = true;
            }

            if (el.textContent.includes("期满") && DATE_RE.test(html)) {
                html = html.replace(DATE_RE, NEW_EXPIRE_DATE);
                changed = true;
            }

            if (changed) el.innerHTML = html;
        });
    }

    /*** 详情页处理函数 ***/
    function replaceInTicketDetail() {
        document.querySelectorAll("li, span, div, h2, h3").forEach(el => {
            let txt = el.textContent.trim();
            if (!txt) return;

            // 改名字
            if (txt === OLD_NAME) {
                el.textContent = NEW_NAME;
            }

            // 改生日
            if (/^\(\*\*\d{4}\)$/.test(txt)) {
                el.textContent = NEW_BIRTHDAY;
            }
        });
    }

    /*** 我的信息页处理函数(无闪烁版本) ***/
    function replaceInMyInfoNode(node) {
        if (node.nodeType !== 1) return; // 只处理元素节点

        // 如果是 <dt> 并且内容是“预订者姓名”
        if (node.tagName.toLowerCase() === 'dt' && node.textContent.includes("预订者姓名")) {
            const dd = node.nextElementSibling;
            if (dd && dd.tagName.toLowerCase() === 'dd') {
                if (dd.textContent.includes(OLD_NAME)) {
                    dd.textContent = dd.textContent.replace(OLD_NAME, NEW_NAME);
                }
            }
        }

        // 如果是 <dd>,也检查是否含有旧名字
        if (node.tagName && node.tagName.toLowerCase() === 'dd' && node.textContent.includes(OLD_NAME)) {
            node.textContent = node.textContent.replace(OLD_NAME, NEW_NAME);
        }
    }

    function replaceInMyInfo() {
        document.querySelectorAll('dt').forEach(dt => {
            if (dt.textContent.includes("预订者姓名")) {
                const dd = dt.nextElementSibling;
                if (dd && dd.tagName.toLowerCase() === 'dd' && dd.textContent.includes(OLD_NAME)) {
                    dd.textContent = dd.textContent.replace(OLD_NAME, NEW_NAME);
                }
            }
        });
    }

    /*** 路由匹配 ***/
    function run() {
        const url = location.href;
        if (/\/my-info\/reservations\//.test(url)) {
            replaceInMyInfo();
        } else if (/\/tickets\.interpark\.com\/mt\/detail/.test(url)) {
            replaceInTicketDetail();
        } else {
            replaceInHome();
        }
    }

    /*** MutationObserver 去抖 + 无闪烁处理 ***/
    let timer = null;
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                // 在节点插入时立即处理“我的信息页”节点
                if (/\/my-info\/reservations\//.test(location.href)) {
                    replaceInMyInfoNode(node);
                }
            });
        });

        // 仍然保留去抖统一处理(主页/详情页)
        if (timer) clearTimeout(timer);
        timer = setTimeout(run, 50);
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });

    // 初始运行一次
    run();
})();