您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Plays audio associated with images on 4chan.
当前为
// ==UserScript== // @name 4chan External Sounds // @namespace b4k // @description Plays audio associated with images on 4chan. // @author Bakugo // @version 1.1.0 // @match *://boards.4chan.org/* // @match *://boards.4channel.org/* // @run-at document-start // ==/UserScript== (function() { var doInit; var doProcessFile; var doProcessFiles; var doPlayFile; var doMakeKey; var players; document.addEventListener( "4chanXInitFinished", function (event) { doInit(); } ); doInit = function () { if (document.documentElement.classList.contains("fourchan-x") == false) { return; } players = {}; doProcessFiles(document.body); ( new MutationObserver( function (mutations) { mutations.forEach( function (mutation) { if (mutation.type === "childList") { mutation.addedNodes.forEach( function (node) { if (node.nodeType === Node.ELEMENT_NODE) { doProcessFiles(node); doPlayFile(node); } } ); } } ); } ) ).observe( document.body, { childList: true, subtree: true } ); }; doProcessFile = function (file) { var fileLink; var fileName; var key; var match; var player; var playerSrc; if (!file.classList.contains("file")) { return; } fileLink = file.querySelector(".file-info > a"); if (!fileLink) { return; } fileName = null; file.querySelectorAll(".file-info .fnfull, .file-info > a") .forEach( function (node) { if (fileName) { return; } if (node && node.textContent) { fileName = node.textContent; } } ); if (!fileName) { return; } fileName = fileName.replace(/\-/, "/"); key = doMakeKey(fileLink.href); if (!key) { return; } if (players[key]) { return; } match = fileName.match(/[\[\(\{]audio[ \=\:\|\$](.*?)[\]\)\}]/i); if (!match) { return; } playerSrc = match[1]; playerSrc = decodeURIComponent(playerSrc); playerSrc = (playerSrc.match(/^(https?\:)?\/\//) ? playerSrc : ("//" + playerSrc)); player = document.createElement("audio"); player.preload = "none"; player.volume = 0.8; player.loop = true; player.src = playerSrc; players[key] = player; }; doProcessFiles = function (target) { target.querySelectorAll(".post") .forEach( function (post) { if (post.parentElement.parentElement.id === "qp") { return; } if (post.parentElement.classList.contains("noFile")) { return; } post.querySelectorAll(".file") .forEach( function (file) { doProcessFile(file); } ); } ); }; doPlayFile = function (target) { var key; var player; var interval; if (!( target.id === "ihover" || target.className === "full-image" )) { return; } key = doMakeKey(target.src); if (!key) { return; } player = players[key]; if (!player) { return; } if (!player.paused) { return; } switch (target.tagName) { case "IMG": player.currentTime = 0; player.loop = true; player.play(); break; case "VIDEO": player.currentTime = target.currentTime; player.loop = false; player.play(); break; default: return; } if (player.paused) { document.dispatchEvent( new CustomEvent("CreateNotification", { bubbles: true, detail: { type: "warning", content: "Your browser blocked autoplay, click anywhere on the page to activate it and try again.", lifetime: 5 } }) ); } interval = setInterval( function () { if (document.body.contains(target)) { if (target.tagName === "VIDEO") { if (player.duration) { if (target.currentTime > player.duration) { player.pause(); } else { if (Math.abs(target.currentTime - player.currentTime) > 0.1) { player.currentTime = target.currentTime; } if (!target.paused && player.paused) { player.play(); } if (target.paused && !player.paused) { player.pause(); } } } } } else { clearInterval(interval); player.pause(); } }, (10) ); }; doMakeKey = function (link) { var match; match = link.match(/\.(?:4cdn|4chan)\.org\/(.+?)\/(\d+?)\.(.+?)$/); if (match) { return (match[1] + "." + match[2]); } return null; }; })();