twitter上很多文字長圖,總是以縮略圖的形式顯示,字根本看不清楚。以前有一些顯示長圖的插件,慢慢的都不能用了,只好自己動手搓了一個。我不會代碼,零基礎,全程AI編程,chrome和Firefox完美兼容,甚至比以前下載的插件體驗更好。現在的程序員太幸福了。
點擊查看代碼
// ==UserScript==
// @name Twitter/X 圖片高清查看器 (v5.3 默認原圖版)
// @namespace http://tampermonkey.net/
// @version 5.3
// @description 默認以原圖(Original)模式打開圖片。支持模態窗口查看、點擊空白/ESC退出。
// @author Expert Analyst
// @match *://twitter.com/*
// @match *://x.com/*
// @match *://*.twitter.com/*
// @match *://*.x.com/*
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
console.log(">>> HD查看器 v5.3 (默認原圖版) 已加載 <<<");
// --- 全局變量 ---
let currentModal = null;
let scrollPosition = 0;
// --- 1. 樣式注入 ---
function injectStyles() {
const style = document.createElement('style');
style.textContent = `
/* 注入在推文圖片上的小按鈕 */
.hd-btn-v5 {
position: absolute; bottom: 6px; right: 6px;
background: rgba(0,0,0,0.6); color: #fff;
border: 1px solid rgba(255,255,255,0.5); border-radius: 4px;
padding: 2px 8px; font-size: 11px; cursor: pointer;
z-index: 90; font-family: system-ui, -apple-system, sans-serif; font-weight: bold;
backdrop-filter: blur(2px); transition: background 0.2s;
}
.hd-btn-v5:hover { background: rgba(29, 155, 240, 0.9); border-color: transparent; }
/* 模態窗口全屏遮罩 */
#hd-modal-overlay {
position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
background: rgba(0, 0, 0, 0.92); z-index: 9999999;
display: flex; flex-direction: column; align-items: center; justify-content: center;
opacity: 0; animation: hd-fade-in 0.2s forwards;
}
/* 圖片滾動容器 */
#hd-image-wrapper {
width: 100%; height: 100%;
display: flex; align-items: center; justify-content: center;
overflow: auto;
padding: 0;
}
/* 圖片通用樣式 */
.hd-viewer-img {
transition: transform 0.2s;
display: block;
}
/* --- 視圖模式 --- */
/* 適屏: 完整顯示圖片 */
.hd-mode-contain .hd-viewer-img {
max-width: 100vw; max-height: 100vh;
width: auto; height: auto;
object-fit: contain; cursor: zoom-in;
}
/* 適寬: 寬度填滿 */
.hd-mode-width #hd-image-wrapper {
display: block;
overflow-y: scroll;
}
.hd-mode-width .hd-viewer-img {
width: 100vw; height: auto;
max-width: none; max-height: none;
margin: 0 auto; cursor: zoom-out;
}
/* 原圖 (默認): 原始像素顯示 */
.hd-mode-original #hd-image-wrapper {
display: flex; align-items: flex-start; justify-content: center;
overflow: scroll;
}
.hd-mode-original .hd-viewer-img {
width: auto; height: auto;
max-width: none; max-height: none;
cursor: zoom-out;
}
/* --- 底部控制欄 --- */
#hd-controls {
position: fixed;
bottom: 20px; right: 20px;
background: rgba(0, 0, 0, 0.5);
padding: 8px 12px; border-radius: 8px;
display: flex; gap: 8px;
border: 1px solid rgba(255,255,255,0.1);
opacity: 0.4;
transition: opacity 0.3s, background 0.3s;
}
#hd-controls:hover {
opacity: 1;
background: rgba(0, 0, 0, 0.85);
}
.hd-control-btn {
background: transparent; border: 1px solid rgba(255,255,255,0.3); color: white;
padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 12px;
transition: all 0.2s; white-space: nowrap;
}
.hd-control-btn:hover { background: rgba(255,255,255,0.2); border-color: white; }
.hd-control-btn.active { background: #1d9bf0; border-color: #1d9bf0; color: white; font-weight: bold; }
/* 關閉按鈕 */
#hd-close-btn {
position: fixed; top: 20px; right: 20px;
width: 40px; height: 40px; border-radius: 50%;
background: rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.2); color: white;
font-size: 24px; cursor: pointer; display: flex; align-items: center; justify-content: center;
transition: background 0.2s; z-index: 100;
}
#hd-close-btn:hover { background: rgba(255,255,255,0.4); }
@keyframes hd-fade-in { from { opacity: 0; } to { opacity: 1; } }
`;
document.head.appendChild(style);
}
// --- 2. 模態窗口邏輯 ---
function openModal(url) {
if (currentModal) return;
// 鎖定背景滾動
scrollPosition = window.scrollY;
document.body.style.overflow = 'hidden';
// 創建DOM
const overlay = document.createElement('div');
overlay.id = 'hd-modal-overlay';
// === 修改點:默認設置為原圖模式 ===
overlay.className = 'hd-mode-original';
overlay.innerHTML = `
<div id="hd-image-wrapper">
<img src="${url}" class="hd-viewer-img" alt="高清圖片">
</div>
<button id="hd-close-btn" title="關閉 (ESC)">×</button>
<div id="hd-controls">
<button class="hd-control-btn" data-mode="contain">適屏</button>
<button class="hd-control-btn" data-mode="width">適寬</button>
<button class="hd-control-btn active" data-mode="original">原圖</button>
</div>
`;
document.body.appendChild(overlay);
currentModal = overlay;
const imgWrapper = overlay.querySelector('#hd-image-wrapper');
const img = overlay.querySelector('.hd-viewer-img');
const btns = overlay.querySelectorAll('.hd-control-btn');
// 事件:點擊空白處關閉
imgWrapper.addEventListener('click', (e) => {
if (e.target === imgWrapper) closeModal();
});
// 事件:點擊關閉按鈕
overlay.querySelector('#hd-close-btn').addEventListener('click', closeModal);
// 事件:ESC 鍵關閉
const escHandler = (e) => {
if (e.key === 'Escape') {
e.preventDefault();
e.stopPropagation();
closeModal();
}
};
window.addEventListener('keydown', escHandler, { capture: true });
// 事件:模式切換按鈕
btns.forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
btns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const mode = btn.dataset.mode;
overlay.className = `hd-mode-${mode}`;
if (mode === 'width') imgWrapper.scrollTop = 0;
});
});
// 事件:點擊圖片快速切換 (原圖 <-> 適屏)
// 邏輯調整:如果當前是適屏,切原圖;如果當前是原圖,切適屏。
img.addEventListener('click', (e) => {
e.stopPropagation();
const isContain = overlay.classList.contains('hd-mode-contain');
// 如果現在是適屏,就點原圖按鈕;否則點適屏按鈕
const targetBtn = isContain ? '[data-mode="original"]' : '[data-mode="contain"]';
overlay.querySelector(targetBtn).click();
});
// 掛載清理函數
overlay.cleanup = () => {
window.removeEventListener('keydown', escHandler, { capture: true });
};
}
function closeModal() {
if (!currentModal) return;
if (currentModal.cleanup) currentModal.cleanup();
currentModal.remove();
currentModal = null;
document.body.style.overflow = '';
window.scrollTo(0, scrollPosition);
}
// --- 3. 按鈕注入邏輯 ---
function initObserver() {
setInterval(() => {
const images = document.querySelectorAll('img[src*="pbs.twimg.com/media/"]');
images.forEach(img => {
if (img.hasAttribute('data-hd-v5')) return;
let parent = img.parentElement;
for(let i=0; i<3; i++) {
if(!parent) break;
const testId = parent.getAttribute('data-testid');
if(testId === 'tweetPhoto' || testId === 'mediaContainer') break;
parent = parent.parentElement;
}
if (!parent) parent = img.parentElement;
if (parent) {
img.setAttribute('data-hd-v5', 'true');
const style = window.getComputedStyle(parent);
if (style.position === 'static') {
parent.style.position = 'relative';
}
const btn = document.createElement('div');
btn.className = 'hd-btn-v5';
btn.innerText = 'HD';
btn.title = '查看高清大圖';
btn.onclick = (e) => {
e.preventDefault();
e.stopPropagation();
const urlObj = new URL(img.src);
urlObj.searchParams.set('name', 'orig');
openModal(urlObj.toString());
};
parent.appendChild(btn);
}
});
}, 800);
}
// --- 4. 啓動 ---
if (document.readyState === 'complete') {
injectStyles();
initObserver();
} else {
window.addEventListener('load', () => {
injectStyles();
initObserver();
});
}
})();
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。