您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows the full sized image for every thumbnail in a page.
// ==UserScript== // @name Explode Thumbs // @description Shows the full sized image for every thumbnail in a page. // @match file:///* // @match *://*/* // @version 2025.02.01 // @author Diogo Kollross // @collaborator Schimon Jehudah // @namespace i2p.schimon.explode-thumbs // @license Unknown // @homepageURL https://greasyfork.org/scripts/522208-explode-thumbs // @supportURL https://greasyfork.org/scripts/522208-explode-thumbs/feedback // @run-at context-menu // ==/UserScript== const AutoscrollStepDelay = 50; // We get all images inside links for now. We check if they really // are thumbnails later. var allThumbs; allThumbs = document.evaluate( '//a[@href]/img[@src]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); // overlayHtml also works as a flag. If there is any constructed HTML // it means we found at least one thumbnail. var overlayHtml = ''; for (var i = 0; i < allThumbs.snapshotLength; i++) { var thumb = allThumbs.snapshotItem(i); var thumbImage = thumb.src; var parentLink = thumb.parentNode; var linkHref = parentLink.href; // Every link that is an image and points to another image is // considered a thumbnail. I wish there was a better way to know // if a URL is an image, but I think this will work for most cases. if (/[.](bmp|gif|jpe?g|png|svg)$/.test(linkHref)) { overlayHtml += '<p style="margin: 0.5em 0.1em"><img style="width: 100%;" src="' + linkHref + '" /></p>' ; } } if (overlayHtml) { var overlay = document.createElement('div'); with (overlay.style) { padding = '0em 0.5em'; borderRight = 'dashed #999 2px'; borderBottom = 'dashed #999 2px'; background = 'white'; position = 'absolute'; top = '0'; left = '0'; width = '100%'; // Some sites use some weird complex layout, so we put // our overlay right in front of everyone to make sure it // does not get covered. zIndex = '10000'; } document.body.insertBefore(overlay, document.body.firstChild); overlayHtml = '<div style="position: fixed; background: #eee; top: 0;' + ' left: 0; right: 0; padding: 0.5em 0.5em;' + 'border-bottom: solid #ccc 1px">' + '<div style="float: left">' + '<button>Autoscroll</button>' + ' <select>' + '<option value="1">1 second/image</option>' + '<option value="5">5 seconds/image</option>' + '<option value="10">10 seconds/image</option>' + '<option value="15">15 seconds/image</option>' + '<option value="20">20 seconds/image</option>' + '</select>' + ' <button disabled="yes">Stop</button>' + '</div>' + '<div style="text-align: right">' + '<button>Hide</button>' + ' <button disabled="yes">Show</button>' //+ '<button>∧</button>' //+ ' <button disabled="yes">∨</button>' + ' <button>Close</button>' + '</div>' + '</div>' + '<div style="margin-top: 3.2em">' + overlayHtml + '</div>' ; overlay.innerHTML = overlayHtml; var toolbarDiv = overlay.firstChild; window.addEventListener( 'load', function() { toolbarDiv.style.width = getComputedStyle(overlay, '').width; }, true ); var imagesDiv = overlay.childNodes.item(1); var leftButtons = toolbarDiv.firstChild; var autoscrollButton = leftButtons.childNodes.item(0); var autoscrollDelay = leftButtons.childNodes.item(2); var stopButton = leftButtons.childNodes.item(4); var rightButtons = toolbarDiv.childNodes.item(1); var hideButton = rightButtons.firstChild; var showButton = rightButtons.childNodes.item(2); var closeButton = rightButtons.childNodes.item(4); autoscrollDelay.value = GM_getValue('autoscroll.delay', 10).toString() ; // timeoutId is used to cancel the autoscroll function so // we leave it out here where it can be seen by the Stop button // onclick handler. var timeoutId = null; function autoScroll(position, deltaY, steps) { if (steps) { position += deltaY; window.scrollTo(0, position); timeoutId = window.setTimeout( function() { autoScroll(position, deltaY, steps - 1); }, AutoscrollStepDelay ); } else { autoscrollButton.disabled = false; autoscrollDelay.disabled = false; stopButton.disabled = true; hideButton.disabled = false; } } // Some magic is used here to set the onclick handler of the // created controls. It seems that this must be used to set // any event handler from GreaseMonkey scripts. The call to // event.preventDefault avoids bubbling of the click event. autoscrollButton.addEventListener( 'click', function(event) { autoscrollButton.disabled = true; autoscrollDelay.disabled = true; stopButton.disabled = false; hideButton.disabled = true; var expandedImages = overlay.getElementsByTagName('img'); var imageCount = expandedImages.length; var expandedTop = expandedImages[0].offsetTop; var availableHeight = window.innerHeight - toolbarDiv.offsetHeight; var lastImage = expandedImages[imageCount - 1]; var totalDelta = lastImage.offsetTop + lastImage.offsetHeight - expandedTop ; var offscreenDelta = Math.max( 0, totalDelta - availableHeight ); var totalTime = parseInt(autoscrollDelay.value) * 1000 * imageCount ; var steps = totalTime / AutoscrollStepDelay; var deltaY = offscreenDelta / steps; var firstPosition = expandedTop - toolbarDiv.offsetHeight; window.scrollTo(0, firstPosition); timeoutId = window.setTimeout( function() { autoScroll(firstPosition, deltaY, steps); }, AutoscrollStepDelay ); event.preventDefault(); }, true ); autoscrollDelay.addEventListener( 'change', function(event) { GM_setValue( 'autoscroll.delay', parseInt(autoscrollDelay.value) ); event.preventDefault(); }, true ); stopButton.addEventListener( 'click', function(event) { window.clearTimeout(timeoutId); timeoutId = null; autoscrollButton.disabled = false; autoscrollDelay.disabled = false; stopButton.disabled = true; hideButton.disabled = false; event.preventDefault(); }, true ); hideButton.addEventListener( 'click', function(event) { autoscrollButton.disabled = true; autoscrollDelay.disabled = true; hideButton.disabled = true; showButton.disabled = false; imagesDiv.style.visibility = 'hidden'; var toolbarDivStyle = getComputedStyle(toolbarDiv, ''); overlay.style.height = parseInt(toolbarDivStyle.height) + parseInt(toolbarDivStyle.paddingTop) + parseInt(toolbarDivStyle.paddingBottom) + 'px' ; overlay.style.position = 'fixed'; overlay.style.opacity = '0.75'; event.preventDefault(); }, true ); showButton.addEventListener( 'click', function(event) { autoscrollButton.disabled = false; autoscrollDelay.disabled = false; hideButton.disabled = false; showButton.disabled = true; imagesDiv.style.visibility = 'visible'; overlay.style.height = 'auto'; overlay.style.position = 'absolute'; overlay.style.opacity = '1'; event.preventDefault(); }, true ); closeButton.addEventListener( 'click', function(event) { if (timeoutId != null) { window.clearTimeout(timeoutId); } overlay.parentNode.removeChild(overlay); event.preventDefault(); }, true ); }