您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Download photos and videos from Threads quickly and easily!
当前为
- // ==UserScript==
- // @license MIT
- // @name Threads Video Downloader
- // @namespace http://tampermonkey.net/
- // @version 1.0
- // @description Download photos and videos from Threads quickly and easily!
- // @author Your Name
- // @match https://*.threads.net/*
- // @grant GM_download
- // ==/UserScript==
- (() => {
- const t = {
- observeDom() {
- let self = this;
- document.querySelectorAll("video").forEach(video => {
- let root = self.findRoot(video);
- root.querySelector(".dw") || root.append(self.getBtn(video.src || null))
- });
- document.querySelectorAll("img").forEach(img => {
- if (!(img.width < 200 || img.height < 200 || img.parentElement.querySelector(".dw")))
- return img.parentElement.prepend(self.getBtn(img.src || null))
- })
- },
- initObserver() {
- if (typeof MutationObserver !== "undefined") {
- const observer = new MutationObserver(() => {
- this.observeDom();
- });
- observer.observe(document.body, { childList: true, subtree: true });
- } else {
- // Fallback for older browsers lacking MutationObserver support
- setInterval(() => {
- this.observeDom();
- }, 500);
- }
- // Initialize observation immediately on load
- this.observeDom();
- },
- getBtn(src) {
- let btn = document.createElement("button");
- btn.innerText = "Download";
- btn.className = "dw";
- let icon = document.createElement("span");
- icon.className = "icon";
- btn.append(icon);
- // Use data attribute instead of "src"
- btn.dataset.src = src;
- btn.addEventListener("click", this.dw);
- return btn;
- },
- findRoot(elem) {
- let parent = elem.parentNode;
- if (!parent) return;
- let visualDiv = parent.querySelector("div[data-visualcompletion]");
- return visualDiv || this.findRoot(parent);
- },
- dw(event) {
- event.preventDefault();
- event.stopPropagation();
- let btn = event.target.nodeName.toLowerCase() === "button" ? event.target : event.target.parentElement;
- let src = btn.dataset.src || null;
- src && GM_download(src, "downloaded_file");
- }
- };
- // Start observers
- t.initObserver();
- })();