twitter长图浏览优化
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();
});
}
})();
浙公网安备 33010602011771号