// ==UserScript== // @name 龙空图片自动缩小 // @namespace https://greasyfork.org/zh-CN/users/1292139-camellya-phoebe // @version 1.0 // @author Phoebe // @description 自动缩小 lkong.net 网站帖子里的图片,预览弹窗图片保持不变。 // @match *://*.lkong.com/* // @match *://*.lkong.net/* // @grant GM_addStyle // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/576465/%E9%BE%99%E7%A9%BA%E5%9B%BE%E7%89%87%E8%87%AA%E5%8A%A8%E7%BC%A9%E5%B0%8F.user.js // @updateURL https://update.greasyfork.icu/scripts/576465/%E9%BE%99%E7%A9%BA%E5%9B%BE%E7%89%87%E8%87%AA%E5%8A%A8%E7%BC%A9%E5%B0%8F.meta.js // ==/UserScript== (function() { 'use strict'; // 注入CSS样式 GM_addStyle(` /* 正常文档流中的帖子图片缩小显示 */ img.lk-shrink-img { max-width: 200px !important; max-height: 200px !important; object-fit: contain !important; cursor: zoom-in !important; transition: opacity 0.2s ease !important; border-radius: 4px; } /* 悬浮预览的大图样式 */ #lk-hover-zoom { position: fixed !important; z-index: 999999 !important; pointer-events: none !important; box-shadow: 0 4px 12px rgba(0,0,0,0.5) !important; border-radius: 4px !important; background: #fff !important; max-width: 80vw !important; max-height: 80vh !important; object-fit: contain !important; opacity: 0; transition: opacity 0.2s ease !important; display: block; } #lk-hover-zoom.lk-show { opacity: 1; } `); // 创建悬浮大图DOM元素 const hoverImg = document.createElement('img'); hoverImg.id = 'lk-hover-zoom'; document.body.appendChild(hoverImg); // 遍历处理页面中的图片 function processImages() { document.querySelectorAll('img').forEach(img => { if (img.id === 'lk-hover-zoom') return; // 排除悬浮预览图自身 if (img.classList.contains('lk-shrink-img') || img.classList.contains('lk-shrink-ignore')) return; // 如果图片尚未加载完成,等加载完再判断尺寸 if (!img.complete) { img.addEventListener('load', () => checkAndAddClass(img), { once: true }); } else { checkAndAddClass(img); } }); } // 判断图片是否符合缩小条件并添加类名 function checkAndAddClass(img) { if (img.classList.contains('lk-shrink-img') || img.classList.contains('lk-shrink-ignore')) return; // 如果图片位于预览/遮罩层内,则忽略,保持原样 if (isInOverlay(img)) { img.classList.add('lk-shrink-ignore'); return; } // 获取图片原始尺寸 const w = img.naturalWidth || img.width; const h = img.naturalHeight || img.height; // 宽或高大于150px的才算内容大图,进行缩小;小图标和表情忽略 if (w > 150 || h > 150) { img.classList.add('lk-shrink-img'); } else { img.classList.add('lk-shrink-ignore'); } } // 判断元素是否处于浮层/遮罩/预览弹窗内 function isInOverlay(el) { let parent = el.parentElement; while (parent && parent !== document.body) { const style = window.getComputedStyle(parent); const zIndex = parseInt(style.zIndex); // 如果父级是 fixed 或 absolute 定位,且 z-index 较高,且占据了屏幕较大面积,则认为是弹窗预览 if ((style.position === 'fixed' || style.position === 'absolute') && zIndex > 100) { const rect = parent.getBoundingClientRect(); if (rect.width > window.innerWidth * 0.5 && rect.height > window.innerHeight * 0.5) { return true; } } parent = parent.parentElement; } return false; } // 监听鼠标悬浮事件 document.addEventListener('mouseover', (e) => { const img = e.target; if (img.classList.contains('lk-shrink-img')) { // 优先加载高清原图(若有 data-src 或 data-original 等懒加载属性) hoverImg.src = img.dataset.original || img.dataset.src || img.src; // 延迟显示,防止鼠标快速划过时频繁闪烁 setTimeout(() => { if (hoverImg.src === (img.dataset.original || img.dataset.src || img.src)) { hoverImg.classList.add('lk-show'); updateHoverImgPosition(e); } }, 150); } }); // 监听鼠标移动,让悬浮图跟随鼠标 document.addEventListener('mousemove', (e) => { if (hoverImg.classList.contains('lk-show')) { updateHoverImgPosition(e); } }); // 监听鼠标移出,隐藏悬浮图 document.addEventListener('mouseout', (e) => { const img = e.target; if (img.classList.contains('lk-shrink-img')) { hoverImg.classList.remove('lk-show'); hoverImg.src = ''; } }); // 更新悬浮图位置,防止超出屏幕 function updateHoverImgPosition(e) { let x = e.clientX + 15; let y = e.clientY + 15; const rect = hoverImg.getBoundingClientRect(); // 如果右侧放不下,则显示在鼠标左侧 if (x + rect.width > window.innerWidth - 10) { x = e.clientX - rect.width - 15; } // 如果下方放不下,则显示在鼠标上方 if (y + rect.height > window.innerHeight - 10) { y = e.clientY - rect.height - 15; } hoverImg.style.left = x + 'px'; hoverImg.style.top = y + 'px'; } // 监听DOM变化,处理异步加载的图片 const observer = new MutationObserver(processImages); observer.observe(document.body, { childList: true, subtree: true }); // 初始执行一次 processImages(); })();