您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
打印作品名+批量取消追番,手动翻页,悬浮窗口显示作品名,可拖拽、复制、下载TXT,操作提示
// ==UserScript== // @name B站批量取消追番追剧 // @namespace https://github.com/kelselchan/bilibili-batch-cancel // @version 2.0 // @description 打印作品名+批量取消追番,手动翻页,悬浮窗口显示作品名,可拖拽、复制、下载TXT,操作提示 // @match https://space.bilibili.com/*/bangumi* // @grant none // @author kelsey chan // @license MIT // ==/UserScript== (function() { 'use strict'; function sleep(ms){ return new Promise(resolve => setTimeout(resolve, ms)); } let collectedTitles = []; // 打印当前页作品名 function collectCurrentPageTitles(){ let titles = Array.from(document.querySelectorAll('.bili-bangumi-card__title')) .map(el => el.innerText.trim()); if(titles.length === 0){ console.log("本页没有找到作品名,请确认页面已完全加载。"); return; } collectedTitles.push(...titles); console.log("本页作品名:", titles); updateFloatingWindow(); } // 左侧悬浮窗口(粉色,可拖拽、复制、下载) let floatingWindow = document.createElement('div'); floatingWindow.style.position = 'fixed'; floatingWindow.style.top = '80px'; floatingWindow.style.left = '0'; floatingWindow.style.width = '220px'; floatingWindow.style.maxHeight = '80vh'; floatingWindow.style.overflowY = 'auto'; floatingWindow.style.backgroundColor = 'rgba(255,182,193,0.95)'; floatingWindow.style.color = 'black'; floatingWindow.style.padding = '8px'; floatingWindow.style.zIndex = 9999; floatingWindow.style.fontSize = '12px'; floatingWindow.style.borderRadius = '0 6px 6px 0'; floatingWindow.style.cursor = 'move'; document.body.appendChild(floatingWindow); // 提示文字 let hintText = document.createElement('div'); hintText.innerText = '保持鼠标悬浮在三个点位置'; hintText.style.fontSize = '11px'; hintText.style.color = '#444'; hintText.style.marginBottom = '4px'; floatingWindow.appendChild(hintText); // 复制按钮 let copyBtn = document.createElement('button'); copyBtn.innerText = '复制'; copyBtn.style.display = 'block'; copyBtn.style.width = '100%'; copyBtn.style.marginBottom = '4px'; copyBtn.style.padding = '4px'; copyBtn.style.fontSize = '12px'; copyBtn.style.cursor = 'pointer'; copyBtn.style.backgroundColor = '#ff69b4'; copyBtn.style.border = 'none'; copyBtn.style.borderRadius = '4px'; copyBtn.style.color = 'white'; copyBtn.onclick = () => { if(collectedTitles.length === 0) return; navigator.clipboard.writeText(collectedTitles.join('\n')) .then(()=>alert('已复制到剪贴板 ✅')) .catch(()=>alert('复制失败 ❌')); }; floatingWindow.appendChild(copyBtn); // 下载 TXT 按钮 let downloadBtn = document.createElement('button'); downloadBtn.innerText = '下载 TXT'; downloadBtn.style.display = 'block'; downloadBtn.style.width = '100%'; downloadBtn.style.marginBottom = '4px'; downloadBtn.style.padding = '4px'; downloadBtn.style.fontSize = '12px'; downloadBtn.style.cursor = 'pointer'; downloadBtn.style.backgroundColor = '#ff69b4'; downloadBtn.style.border = 'none'; downloadBtn.style.borderRadius = '4px'; downloadBtn.style.color = 'white'; downloadBtn.onclick = () => { if(collectedTitles.length === 0) return; let blob = new Blob([collectedTitles.join('\n')], {type: 'text/plain'}); let a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'B站作品名.txt'; a.click(); URL.revokeObjectURL(a.href); }; floatingWindow.appendChild(downloadBtn); let listArea = document.createElement('div'); listArea.style.fontSize = '11px'; listArea.style.maxHeight = '70vh'; listArea.style.overflowY = 'auto'; floatingWindow.appendChild(listArea); // 拖拽逻辑 let isDragging = false, offsetX=0, offsetY=0; floatingWindow.addEventListener('mousedown', (e)=>{ if(e.target===copyBtn || e.target===downloadBtn) return; isDragging = true; offsetX = e.clientX - floatingWindow.offsetLeft; offsetY = e.clientY - floatingWindow.offsetTop; e.preventDefault(); }); document.addEventListener('mousemove', (e)=>{ if(isDragging){ let x = e.clientX - offsetX; let y = e.clientY - offsetY; x = Math.max(0, Math.min(window.innerWidth - floatingWindow.offsetWidth, x)); y = Math.max(0, Math.min(window.innerHeight - floatingWindow.offsetHeight, y)); floatingWindow.style.left = x + 'px'; floatingWindow.style.top = y + 'px'; } }); document.addEventListener('mouseup', ()=>{ isDragging = false; }); function updateFloatingWindow(){ listArea.innerHTML = ''; collectedTitles.forEach(title=>{ let p = document.createElement('p'); p.innerText = title; p.style.margin = '2px 0'; listArea.appendChild(p); }); } // 单条取消(鼠标经过 + 点击取消) async function cancelOne(moreBtn){ try{ moreBtn.dispatchEvent(new MouseEvent('mouseover', { bubbles: true })); await sleep(1000); let cancelBtn = Array.from(document.querySelectorAll('.menu-popover__panel-item')) .find(el => el.innerText.includes('取消追')); if(cancelBtn) cancelBtn.click(); }catch(e){ console.log('取消失败:', e); } } // 批量取消当前页 async function cancelPage(){ let moreBtns = document.querySelectorAll('.sic-BDC-more_vertical_fill'); for(let btn of moreBtns){ await cancelOne(btn); await sleep(2000 + Math.random()*1000); } alert("本页批量取消完成 ✅"); } // 添加操作按钮(挂在“看过”旁边) function addControlButtons(){ let sawItem = Array.from(document.querySelectorAll('.radio-filter__item')) .find(el => el.innerText.includes('看过')); if(!sawItem) return; if(document.getElementById('bangumi-control-btns')) return; let container = document.createElement('div'); container.id = 'bangumi-control-btns'; container.style.display='inline-flex'; container.style.alignItems='center'; container.style.marginLeft='8px'; // 提示文字 let tip = document.createElement('div'); tip.innerText = '➡ 进入下一页再点击打印按钮'; tip.style.fontSize = '11px'; tip.style.color = '#ff69b4'; tip.style.marginRight = '6px'; container.appendChild(tip); // 打印按钮 let btn1 = document.createElement('button'); btn1.innerText = '打印本页作品名'; btn1.style.padding='4px 8px'; btn1.style.marginRight='4px'; btn1.style.fontSize='12px'; btn1.style.cursor='pointer'; btn1.style.backgroundColor = '#ff69b4'; btn1.style.border = 'none'; btn1.style.borderRadius = '4px'; btn1.style.color = 'white'; btn1.onclick = collectCurrentPageTitles; container.appendChild(btn1); // 批量取消按钮 let btn2 = document.createElement('button'); btn2.innerText = '批量取消本页'; btn2.style.padding='4px 8px'; btn2.style.fontSize='12px'; btn2.style.cursor='pointer'; btn2.style.backgroundColor = '#ff69b4'; btn2.style.border = 'none'; btn2.style.borderRadius = '4px'; btn2.style.color = 'white'; btn2.onclick = cancelPage; container.appendChild(btn2); sawItem.parentNode.insertBefore(container, sawItem.nextSibling); } const observer = new MutationObserver(() => addControlButtons()); observer.observe(document.body, { childList:true, subtree:true }); window.addEventListener('load', () => setTimeout(addControlButtons, 2000)); })();