您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
4chan grid based Image Gallery for threads that can load images, images with sounds, webms with sounds (Button on the Bottom Right)
当前为
// ==UserScript== // @name 4chan Gallery // @namespace http://tampermonkey.net/ // @version 2024-03-26 (1.1) // @description 4chan grid based Image Gallery for threads that can load images, images with sounds, webms with sounds (Button on the Bottom Right) // @author TheDarkEnjoyer // @match http://boards.4chan.org/vt/thread/* // @match https://boards.4chan.org/vt/thread/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // @license GNU GPLv3 // ==/UserScript== (function () { "use strict"; // Function to load the button const loadButton = () => { const posts = document.querySelectorAll(".postContainer"); // Check if there are at least two posts if (posts.length >= 2) { const button = document.createElement("button"); button.textContent = "Open Image Gallery"; button.style.position = "fixed"; button.style.bottom = "20px"; button.style.right = "20px"; button.style.zIndex = "1000"; button.style.backgroundColor = "var(--main-color)"; // Dark mode compatible background button.style.color = "var(--text-color)"; // Dark mode compatible text color // Append the button to the body after 2 seconds setTimeout(() => document.body.appendChild(button), 2000); const openImageGallery = () => { const gallery = document.createElement("div"); gallery.style.position = "fixed"; gallery.style.top = "0"; gallery.style.left = "0"; gallery.style.width = "100%"; gallery.style.height = "100%"; gallery.style.backgroundColor = "rgba(0, 0, 0, 0.8)"; gallery.style.display = "flex"; gallery.style.justifyContent = "center"; gallery.style.alignItems = "center"; gallery.style.zIndex = "9999"; const gridContainer = document.createElement("div"); gridContainer.style.display = "grid"; gridContainer.style.gridTemplateColumns = "repeat(auto-fit, minmax(200px, 1fr))"; gridContainer.style.gridGap = "10px"; gridContainer.style.padding = "20px"; gridContainer.style.backgroundColor = "var(--main-color)"; // Dark mode compatible background gridContainer.style.color = "var(--text-color)"; // Dark mode compatible text color gridContainer.style.maxWidth = "80%"; gridContainer.style.maxHeight = "80%"; gridContainer.style.overflowY = "auto"; gridContainer.style.resize = "both"; // Make the grid resizable gridContainer.style.overflow = "auto"; // Add scrollbars when resized gridContainer.style.border = "1px solid var(--text-color)"; // Add border to the grid container // Loop through each post and add its image/video to the grid posts.forEach((post) => { const mediaLink = post.querySelector(".fileText a"); const comment = post.querySelector(".postMessage"); if (mediaLink) { const isVideo = mediaLink.href.includes(".webm"); const fileName = mediaLink.href.split("/").pop(); const soundLink = mediaLink.title.match(/\[sound=(.+?)\]/); const cell = document.createElement("div"); cell.style.border = "1px solid var(--text-color)"; // Add border to each cell cell.style.position = "relative"; // Make the cell position relative const buttonDiv = document.createElement("div"); buttonDiv.style.display = "flex"; buttonDiv.style.justifyContent = "space-between"; buttonDiv.style.alignItems = "center"; buttonDiv.style.padding = "5px"; if (isVideo) { const videoContainer = document.createElement("div"); videoContainer.style.position = "relative"; const video = document.createElement("video"); video.src = mediaLink.href; video.style.maxWidth = "100%"; video.style.maxHeight = "200px"; video.style.objectFit = "contain"; video.muted = true; video.style.cursor = "pointer"; video.addEventListener("click", () => { post.scrollIntoView({ behavior: "smooth" }); document.body.removeChild(gallery); }); video.controls = true; video.title = comment.textContent; videoContainer.appendChild(video); if (soundLink) { const audio = document.createElement("audio"); audio.src = decodeURIComponent(soundLink[1].startsWith("http") ? soundLink[1] : `https://${soundLink[1]}`); videoContainer.appendChild(audio); const playPauseButton = document.createElement("button"); playPauseButton.textContent = "Play/Pause"; playPauseButton.addEventListener("click", () => { if (video.paused && audio.paused) { video.play(); audio.play(); } else { video.pause(); audio.pause(); } }); buttonDiv.appendChild(playPauseButton); const resetButton = document.createElement("button"); resetButton.textContent = "Reset"; resetButton.addEventListener("click", () => { video.currentTime = 0; audio.currentTime = 0; }); buttonDiv.appendChild(resetButton); } const cellButton = document.createElement("button"); cellButton.textContent = "View Post"; cellButton.style.backgroundColor = "var(--main-color)"; cellButton.style.color = "var(--text-color)"; cellButton.addEventListener("click", () => { post.scrollIntoView({ behavior: "smooth" }); document.body.removeChild(gallery); }); buttonDiv.appendChild(cellButton); cell.appendChild(videoContainer); cell.appendChild(buttonDiv); } else { const image = document.createElement("img"); image.src = mediaLink.href; image.style.maxWidth = "100%"; image.style.maxHeight = "200px"; image.style.objectFit = "contain"; image.style.cursor = "pointer"; image.addEventListener("click", () => { post.scrollIntoView({ behavior: "smooth" }); document.body.removeChild(gallery); }); image.title = comment.textContent; if (soundLink) { const audio = document.createElement("audio"); audio.src = decodeURIComponent(soundLink[1].startsWith("http") ? soundLink[1] : `https://${soundLink[1]}`); const playPauseButton = document.createElement("button"); playPauseButton.textContent = "Play/Pause"; playPauseButton.style.position = "absolute"; playPauseButton.style.bottom = "10px"; playPauseButton.style.left = "10px"; playPauseButton.addEventListener("click", () => { if (audio.paused) { audio.play(); } else { audio.pause(); } }); buttonDiv.appendChild(playPauseButton); } cell.appendChild(image); cell.appendChild(buttonDiv); } gridContainer.appendChild(cell); } }); gallery.appendChild(gridContainer); const closeButton = document.createElement("button"); closeButton.textContent = "Close"; closeButton.style.position = "absolute"; closeButton.style.top = "10px"; closeButton.style.right = "10px"; closeButton.style.zIndex = "10000"; closeButton.style.backgroundColor = "var(--main-color)"; closeButton.style.color = "var(--text-color)"; closeButton.addEventListener("click", () => { document.body.removeChild(gallery); }); gallery.appendChild(closeButton); document.body.appendChild(gallery); }; button.addEventListener("click", openImageGallery); } else { // If there are less than two posts, try again after 5 seconds setTimeout(loadButton, 5000); } }; loadButton(); console.log("4chan Gallery loaded successfully!"); })();