您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
更可靠的页面时区修改方法,带有友好的选择界面
// ==UserScript== // @name 增强版时区劫持(改进UI) // @namespace http://tampermonkey.net/ // @version 1.2 // @description 更可靠的页面时区修改方法,带有友好的选择界面 // @author kendrick // @match *://*.sankuai.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @run-at document-start // @license MIT // ==/UserScript== (function() { 'use strict'; // 定义可用时区及其偏移量(分钟) const TIMEZONES = { 'default': { name: '系统默认', offset: null }, 'china': { name: '中国 (UTC+8)', offset: -480 }, 'europe': { name: '欧洲 (UTC+1)', offset: -60 }, 'middleeast': { name: '中东 (UTC+3)', offset: -180 } }; // 获取保存的时区设置,默认为系统时区 const selectedTimezone = GM_getValue('selectedTimezone', 'default'); // 添加CSS样式 GM_addStyle(` .tz-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 10000; } .tz-modal { background: white; border-radius: 8px; padding: 20px; width: 300px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } .tz-modal-title { font-size: 18px; font-weight: bold; margin-bottom: 15px; text-align: center; color: #333; } .tz-options { display: flex; flex-direction: column; gap: 10px; } .tz-option { padding: 12px; border: 1px solid #ddd; border-radius: 6px; cursor: pointer; transition: all 0.2s; background: #f8f8f8; text-align: center; } .tz-option:hover { background: #e8f0fe; border-color: #4285f4; } .tz-option.selected { background: #e8f0fe; border-color: #4285f4; position: relative; } .tz-option.selected::after { content: "✓"; position: absolute; right: 10px; color: #4285f4; } .tz-indicator { position: fixed; bottom: 10px; right: 10px; background: rgba(0,0,0,0.7); color: white; padding: 5px 10px; border-radius: 3px; font-size: 12px; z-index: 9999; cursor: pointer; opacity: 0.7; transition: opacity 0.3s; } .tz-indicator:hover { opacity: 1; } `); // 如果选择了默认时区,则不进行劫持 if (selectedTimezone === 'default') { setupMenuCommands(); return; } // 获取目标时区偏移 const targetOffset = TIMEZONES[selectedTimezone].offset; // 执行注入脚本 injectScript(); // 设置菜单命令 setupMenuCommands(); // 在页面完全加载后添加时区指示器 window.addEventListener('load', function() { addTimezoneIndicator(); }); // 注入脚本到页面 function injectScript() { const scriptText = ` (function() { // 保存原始Date对象 const OriginalDate = Date; // 目标时区偏移(分钟) const targetOffset = ${targetOffset}; // 获取本地时区偏移 const localOffset = new OriginalDate().getTimezoneOffset(); // 计算时区差异(分钟) const offsetDiff = localOffset - targetOffset; // 创建自定义Date构造函数 function CustomDate() { // 处理不同构造函数调用情况 if (arguments.length === 0) { // 无参数调用 - 返回当前时间,但调整为目标时区 const date = new OriginalDate(); date.setTime(date.getTime() + offsetDiff * 60 * 1000); return date; } else { // 有参数调用 - 正常创建日期对象 return new (Function.prototype.bind.apply( OriginalDate, [null].concat(Array.prototype.slice.call(arguments)) ))(); } } // 复制静态方法 CustomDate.UTC = OriginalDate.UTC; CustomDate.parse = OriginalDate.parse; // 修改now方法以反映目标时区 CustomDate.now = function() { return OriginalDate.now() + offsetDiff * 60 * 1000; }; // 继承原型 CustomDate.prototype = OriginalDate.prototype; // 修改getTimezoneOffset方法 const originalGetTimezoneOffset = OriginalDate.prototype.getTimezoneOffset; OriginalDate.prototype.getTimezoneOffset = function() { return targetOffset; }; // 覆盖全局Date对象 window.Date = CustomDate; // 输出调试信息 console.log('[时区修改器] 已将时区修改为: ${TIMEZONES[selectedTimezone].name}'); // 验证劫持是否成功 const testDate = new Date(); console.log('[时区修改器] 当前时间:', testDate.toLocaleString()); console.log('[时区修改器] 时区偏移:', testDate.getTimezoneOffset(), '分钟'); })(); `; // 创建脚本元素 const scriptElement = document.createElement('script'); scriptElement.textContent = scriptText; // 确保脚本尽早执行 if (document.documentElement) { document.documentElement.appendChild(scriptElement); document.documentElement.removeChild(scriptElement); } else { // 如果documentElement不可用,则等待它可用 const observer = new MutationObserver(function(mutations, obs) { if (document.documentElement) { document.documentElement.appendChild(scriptElement); document.documentElement.removeChild(scriptElement); obs.disconnect(); } }); observer.observe(document, { childList: true, subtree: true }); } } // 创建时区选择器对话框 function createTimezoneSelector() { // 创建已有的模态框覆盖层 if (document.querySelector('.tz-modal-overlay')) { return; } const overlay = document.createElement('div'); overlay.className = 'tz-modal-overlay'; const modal = document.createElement('div'); modal.className = 'tz-modal'; const title = document.createElement('div'); title.className = 'tz-modal-title'; title.textContent = '选择时区'; const options = document.createElement('div'); options.className = 'tz-options'; // 创建时区选项 for (const [key, value] of Object.entries(TIMEZONES)) { const option = document.createElement('div'); option.className = 'tz-option'; if (key === selectedTimezone) { option.classList.add('selected'); } option.textContent = value.name; option.dataset.timezone = key; option.addEventListener('click', function() { const timezone = this.dataset.timezone; GM_setValue('selectedTimezone', timezone); overlay.remove(); alert(`已将时区设置为: ${TIMEZONES[timezone].name}\n请刷新页面以应用更改`); location.reload(); }); options.appendChild(option); } // 组装模态框 modal.appendChild(title); modal.appendChild(options); overlay.appendChild(modal); // 点击覆盖层关闭模态框 overlay.addEventListener('click', function(e) { if (e.target === overlay) { overlay.remove(); } }); document.body.appendChild(overlay); } // 设置油猴菜单命令 function setupMenuCommands() { // 时区选择菜单 GM_registerMenuCommand("选择时区", function() { if (document.body) { createTimezoneSelector(); } else { // 如果body还不存在,等待DOM加载完成 window.addEventListener('DOMContentLoaded', createTimezoneSelector); } }); // 显示当前时区设置 GM_registerMenuCommand(`当前时区: ${TIMEZONES[selectedTimezone].name}`, function(){}); } // 添加时区指示器 function addTimezoneIndicator() { if (selectedTimezone === 'default') return; const indicator = document.createElement('div'); indicator.textContent = `🌐 ${TIMEZONES[selectedTimezone].name}`; indicator.className = 'tz-indicator'; indicator.addEventListener('click', function() { createTimezoneSelector(); }); document.body.appendChild(indicator); } })();