// ==UserScript== // @name 万能懒加载触发 + 超级视窗缩放(面板可拖拽) // @namespace qq:1316590732 // @version 9.1 // @description 修复三种懒加载模式 + 可拖拽面板 + 优化按钮样式 // @author 沧桑 // @match *://*/* // @grant none // @license MIT // @run-at document-start // @downloadURL https://update.greasyfork.icu/scripts/576141/%E4%B8%87%E8%83%BD%E6%87%92%E5%8A%A0%E8%BD%BD%E8%A7%A6%E5%8F%91%20%2B%20%E8%B6%85%E7%BA%A7%E8%A7%86%E7%AA%97%E7%BC%A9%E6%94%BE%EF%BC%88%E9%9D%A2%E6%9D%BF%E5%8F%AF%E6%8B%96%E6%8B%BD%EF%BC%89.user.js // @updateURL https://update.greasyfork.icu/scripts/576141/%E4%B8%87%E8%83%BD%E6%87%92%E5%8A%A0%E8%BD%BD%E8%A7%A6%E5%8F%91%20%2B%20%E8%B6%85%E7%BA%A7%E8%A7%86%E7%AA%97%E7%BC%A9%E6%94%BE%EF%BC%88%E9%9D%A2%E6%9D%BF%E5%8F%AF%E6%8B%96%E6%8B%BD%EF%BC%89.meta.js // ==/UserScript== (function () { 'use strict'; let currentZoom = 1; let panel = null; let isDragging = false; let startX = 0, startY = 0, startLeft = 0, startTop = 0; let scrollInterval = null; // 用于控制滚动频率 // ========== 核心缩放函数 ========== function setZoom(zoomLevel) { currentZoom = Math.max(0.0001, Math.min(50, zoomLevel)); if ('zoom' in document.body.style) { document.body.style.zoom = currentZoom; } else { document.body.style.transform = `scale(${currentZoom})`; document.body.style.transformOrigin = '0 0'; } updateZoomDisplay(); } function updateZoomDisplay() { if (!panel) return; const display = panel.querySelector('#currentZoomDisplay'); if (display) { display.textContent = currentZoom < 0.01 ? `${currentZoom.toExponential(4)} 倍` : `${currentZoom.toFixed(4)} 倍`; } } // ========== 模拟真实鼠标事件 ========== function simulateMouseEvent(element, eventType) { if (!element) return; const rect = element.getBoundingClientRect(); const x = rect.left + rect.width / 2; const y = rect.top + rect.height / 2; const event = new MouseEvent(eventType, { view: window, bubbles: true, cancelable: true, clientX: x, clientY: y, screenX: x, screenY: y }); element.dispatchEvent(event); } // ========== 触发当前视口内所有图片的加载 ========== function triggerImagesInViewport() { const viewportHeight = window.innerHeight; const viewportWidth = window.innerWidth; const scrollX = window.scrollX || window.pageXOffset; const scrollY = window.scrollY || window.pageYOffset; // 获取所有可能的懒加载图片 const selectors = [ 'img[data-src]', 'img[data-original]', 'img[data-lazy]', 'img[data-lazy-src]', 'img[data-srcset]', 'img[loading="lazy"]', 'img[data-echo]', 'img[data-url]', 'img[data-srcset]', 'img[data-ks-lazyload]', 'img[srcset]', 'img:not([src])', 'iframe[data-src]', 'iframe[data-lazy]' ]; const allImages = document.querySelectorAll(selectors.join(',')); let loadedCount = 0; allImages.forEach(img => { const rect = img.getBoundingClientRect(); // 检查是否在视口内或接近视口(增加200px缓冲) const isInViewport = ( rect.top < viewportHeight + 200 && rect.bottom > -200 && rect.left < viewportWidth + 200 && rect.right > -200 ); if (isInViewport) { // 模拟鼠标悬停 simulateMouseEvent(img, 'mouseenter'); simulateMouseEvent(img, 'mouseover'); // 强制加载图片 if (img.tagName === 'IMG') { if (img.dataset.src && !img.src) img.src = img.dataset.src; if (img.dataset.original && !img.src) img.src = img.dataset.original; if (img.dataset.lazy && !img.src) img.src = img.dataset.lazy; if (img.dataset.lazySrc && !img.src) img.src = img.dataset.lazySrc; if (img.dataset.url && !img.src) img.src = img.dataset.url; if (img.dataset.echo && !img.src) img.src = img.dataset.echo; // 处理 srcset if (img.dataset.srcset && !img.srcset) img.srcset = img.dataset.srcset; loadedCount++; } else if (img.tagName === 'IFRAME') { if (img.dataset.src && !img.src) img.src = img.dataset.src; if (img.dataset.lazy && !img.src) img.src = img.dataset.lazy; loadedCount++; } } }); if (loadedCount > 0) { console.log(`[懒加载] 触发加载 ${loadedCount} 个资源`); } // 触发全局事件 window.dispatchEvent(new Event('scroll')); window.dispatchEvent(new Event('resize')); document.dispatchEvent(new Event('scroll')); document.dispatchEvent(new Event('visibilitychange')); } // ========== 滚动时持续触发加载 ========== function startContinuousTrigger() { if (scrollInterval) clearInterval(scrollInterval); // 每200ms触发一次视口内图片检查 scrollInterval = setInterval(() => { triggerImagesInViewport(); }, 200); } function stopContinuousTrigger() { if (scrollInterval) { clearInterval(scrollInterval); scrollInterval = null; } } // ========== 改进后的懒加载滚动 ========== async function triggerLazyLoad(mode = 'vertical') { console.log(`[懒加载] 开始触发 → 模式: ${mode}`); // 启动持续触发 startContinuousTrigger(); // 先重置到左上角 window.scrollTo({ left: 0, top: 0, behavior: 'auto' }); // 触发一次初始加载 triggerImagesInViewport(); await sleep(300); const totalHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight); const totalWidth = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth); const step = Math.max(220, window.innerHeight * 0.7); // 垂直步长 const hStep = Math.max(280, window.innerWidth * 0.75); // 水平步长 let pos = 0; if (mode === 'horizontal-ltr') { // 从左往右 pos = 0; while (pos <= totalWidth + 600) { window.scrollTo({ left: pos, top: 0, behavior: 'auto' }); await sleep(250); // 增加停留时间,让懒加载有机会加载 triggerImagesInViewport(); // 滚动后立即触发 await sleep(150); pos += hStep; } window.scrollTo({ left: 0, top: 0, behavior: 'smooth' }); } else if (mode === 'horizontal-rtl') { // 从右往左 pos = totalWidth; while (pos >= -600) { window.scrollTo({ left: pos, top: 0, behavior: 'auto' }); await sleep(250); triggerImagesInViewport(); await sleep(150); pos -= hStep; } window.scrollTo({ left: totalWidth, top: 0, behavior: 'smooth' }); } else { // 从上往下(默认) pos = 0; while (pos <= totalHeight + 600) { window.scrollTo({ top: pos, left: 0, behavior: 'auto' }); await sleep(250); triggerImagesInViewport(); await sleep(150); pos += step; } window.scrollTo({ top: 0, behavior: 'smooth' }); } // 最终再触发一次所有图片 await sleep(500); triggerAllImagesManually(); // 停止持续触发 stopContinuousTrigger(); console.log('[懒加载] 完成'); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // ========== 加强版手动触发所有图片和iframe加载 ========== function triggerAllImagesManually() { const selectors = [ 'img[data-src]', 'img[data-original]', 'img[data-lazy]', 'img[data-lazy-src]', 'img[data-srcset]', 'img[loading="lazy"]', 'img[data-echo]', 'img[data-url]', 'img:not([src])', 'img[src=""]', 'img[src="#"]', 'iframe[data-src]', 'iframe[data-lazy]' ]; let loadedCount = 0; document.querySelectorAll(selectors.join(',')).forEach(el => { if (el.tagName === 'IMG') { // 模拟鼠标事件 simulateMouseEvent(el, 'mouseenter'); simulateMouseEvent(el, 'mouseover'); if (el.dataset.src && !el.src) { el.src = el.dataset.src; loadedCount++; } if (el.dataset.original && !el.src) { el.src = el.dataset.original; loadedCount++; } if (el.dataset.lazy && !el.src) { el.src = el.dataset.lazy; loadedCount++; } if (el.dataset.lazySrc && !el.src) { el.src = el.dataset.lazySrc; loadedCount++; } if (el.dataset.url && !el.src) { el.src = el.dataset.url; loadedCount++; } if (el.dataset.srcset && !el.srcset) { el.srcset = el.dataset.srcset; loadedCount++; } } else if (el.tagName === 'IFRAME') { if (el.dataset.src && !el.src) { el.src = el.dataset.src; loadedCount++; } if (el.dataset.lazy && !el.src) { el.src = el.dataset.lazy; loadedCount++; } } }); if (loadedCount > 0) { console.log(`[手动触发] 强制加载 ${loadedCount} 个资源`); } // 触发全局事件 window.dispatchEvent(new Event('scroll')); document.dispatchEvent(new Event('scroll')); document.body.dispatchEvent(new Event('mouseenter')); } // ========== 使用MutationObserver监听新添加的图片 ========== function observeNewImages() { const observer = new MutationObserver((mutations) => { let hasNewImages = false; mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { // Element node if (node.tagName === 'IMG' || node.tagName === 'IFRAME') { hasNewImages = true; } if (node.querySelectorAll) { const images = node.querySelectorAll('img, iframe'); if (images.length > 0) hasNewImages = true; } } }); }); if (hasNewImages) { setTimeout(() => triggerImagesInViewport(), 100); } }); observer.observe(document.body, { childList: true, subtree: true }); console.log('[监听] 已启用新图片监听'); } // ========== 创建面板(保持之前样式) ========== function createPanel() { if (panel && document.documentElement.contains(panel)) return; panel = document.createElement('div'); panel.id = 'super-zoom-panel'; Object.assign(panel.style, { position: 'fixed', top: '20px', right: '20px', width: '350px', background: 'linear-gradient(135deg, #667eea, #764ba2)', color: 'white', borderRadius: '16px', padding: '18px', boxShadow: '0 12px 50px rgba(0,0,0,0.45)', zIndex: '2147483647', fontFamily: 'system-ui, sans-serif', backdropFilter: 'blur(12px)', border: '1px solid rgba(255,255,255,0.3)', userSelect: 'none', transform: 'none !important', zoom: '1 !important' }); panel.innerHTML = `
🔍 沧桑超级视窗
按住标题栏 可拖动面板
版本 9.1 - 需手动点击按钮触发加载
点击跳转,欢迎到B站打赏、充电支持作者,UID:507560163
#####
1.0000 倍
页面缩放比例
懒加载触发模式
`; document.documentElement.appendChild(panel); // 按钮样式 const style = document.createElement('style'); style.textContent = ` #super-zoom-panel .zoom-btn, #super-zoom-panel .lazy-btn, #super-zoom-panel .reset-btn { padding: 12px 8px; border: none; border-radius: 10px; background: rgba(255,255,255,0.22); color: white; font-size: 13.5px; font-weight: 600; cursor: pointer; transition: all 0.2s; } #super-zoom-panel .zoom-btn:hover, #super-zoom-panel .lazy-btn:hover { background: rgba(255,255,255,0.38); transform: translateY(-1px); } #super-zoom-panel .zoom-btn:active, #super-zoom-panel .lazy-btn:active { transform: scale(0.95); } #super-zoom-panel .reset-btn { width: 100%; padding: 13px; background: rgba(255,255,255,0.18); } #super-zoom-panel .reset-btn:hover { background: rgba(255,255,255,0.28); } `; panel.appendChild(style); // 事件绑定 panel.querySelectorAll('button[data-zoom]').forEach(btn => { btn.addEventListener('click', () => setZoom(parseFloat(btn.dataset.zoom))); }); panel.querySelector('#lazyVertical').addEventListener('click', () => triggerLazyLoad('vertical')); panel.querySelector('#lazyLTR').addEventListener('click', () => triggerLazyLoad('horizontal-ltr')); panel.querySelector('#lazyRTL').addEventListener('click', () => triggerLazyLoad('horizontal-rtl')); panel.querySelector('#forceLoadBtn').addEventListener('click', () => triggerAllImagesManually()); panel.querySelector('#resetBtn').addEventListener('click', () => setZoom(1)); panel.querySelector('#closeBtn').addEventListener('click', () => panel.remove()); makeDraggable(panel); updateZoomDisplay(); } // 拖拽功能(保持不变) function makeDraggable(element) { const header = element.querySelector('#panelHeader'); header.addEventListener('mousedown', (e) => { if (e.target.id === 'closeBtn') return; isDragging = true; startX = e.clientX; startY = e.clientY; const rect = element.getBoundingClientRect(); startLeft = rect.left; startTop = rect.top; element.style.transition = 'none'; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; let newLeft = startLeft + (e.clientX - startX); let newTop = startTop + (e.clientY - startY); newLeft = Math.max(10, Math.min(window.innerWidth - element.offsetWidth - 10, newLeft)); newTop = Math.max(10, Math.min(window.innerHeight - element.offsetHeight - 10, newTop)); element.style.left = newLeft + 'px'; element.style.top = newTop + 'px'; element.style.right = 'auto'; element.style.bottom = 'auto'; }); document.addEventListener('mouseup', () => { isDragging = false; if (panel) panel.style.transition = 'all 0.2s'; }); } function keepPanelAlive() { if (!panel || !document.documentElement.contains(panel)) createPanel(); setTimeout(keepPanelAlive, 2000); } function init() { createPanel(); keepPanelAlive(); observeNewImages(); // 监听新添加的图片(仅监听,不自动强制加载) setTimeout(() => setZoom(1), 800); // 【关键修改】移除了页面加载时自动触发图片加载的代码 // 现在需要用户点击面板按钮才会开始加载图片 // 注意:observeNewImages 会持续监听新添加的图片, // 但需要用户先点击触发加载后,才会对后续新图片也生效。 } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();