Bilibili標題旁邊增加封面浮動按鈕

B站增加封面浮動按鈕

// ==UserScript==
// @name         Bilibili標題旁邊增加封面浮動按鈕
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  B站增加封面浮動按鈕
// @author       shanlan(ChatGPT o3-mini)
// @match        *://*.bilibili.com/*
// @grant        none
// @run-at       document-end
// @license MIT
// ==/UserScript==

(function(){
"use strict";
const m = document.querySelector('meta[itemprop="image"]');
if(!m) return;
const imgUrl = m.getAttribute("content").split("@")[0].replace(/^\/\//, "https://");
if(!imgUrl) return;

// 取得標題區塊,找不到時以 body 作 fallback
const getTitle = () => document.querySelector("h1.video-title, .video-title, .tit") || document.body;

// 建立按鈕元素與 tooltip 預覽圖
const createBtn = () => {
const btn = document.createElement("button");
btn.id = "coverBtn";
btn.innerText = "封面";
btn.style.cssText = "margin-left:8px;vertical-align:middle;cursor:pointer;padding:2px 12px;font-size:14px;line-height:22px;height:28px;color:#fff;background:linear-gradient(90deg, #ff8a00 0%, #e52e71 100%);border:none;border-radius:16px;box-shadow:0 1px 4px rgba(0,0,0,0.08);transition:background 0.2s,box-shadow 0.2s,transform 0.1s;outline:none;max-width:64px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;user-select:none;position:relative";
let tip = null;
btn.onmouseenter = ()=>{
btn.style.background = "linear-gradient(90deg, #e52e71 0%, #ff8a00 100%)";
btn.style.boxShadow = "0 2px 8px rgba(229,46,113,0.15)";
btn.style.transform = "translateY(-1px) scale(1.04)";
tip = document.createElement("div");
tip.style.cssText = "position:absolute;border:1px solid #ccc;background:#fff;padding:5px;box-shadow:2px 2px 10px rgba(0,0,0,0.18);z-index:9999;border-radius:8px";
const img = document.createElement("img");
img.src = imgUrl;
const mw = Math.floor(window.innerWidth/2), mh = Math.floor(window.innerHeight/2);
img.style.cssText = `max-width:${mw}px;max-height:${mh}px;display:block;border-radius:4px`;
tip.appendChild(img);
document.body.appendChild(tip);
const r = btn.getBoundingClientRect();
let left = r.right + 10, top = r.top + window.scrollY;
if(left + mw > window.innerWidth) left = window.innerWidth - mw - 10;
if(top + mh > window.innerHeight + window.scrollY) top = window.innerHeight + window.scrollY - mh - 10;
if(top < window.scrollY) top = window.scrollY + 10;
tip.style.left = left + "px";
tip.style.top = top + "px";
};
btn.onmouseleave = ()=>{
btn.style.background = "linear-gradient(90deg, #ff8a00 0%, #e52e71 100%)";
btn.style.boxShadow = "0 1px 4px rgba(0,0,0,0.08)";
btn.style.transform = "none";
tip && tip.remove();
};
btn.onclick = ()=> window.open(imgUrl, "_blank");
return btn;
};

// 若標題區塊內尚無按鈕則添加
const addBtn = () => {
const t = getTitle();
if(t && !t.querySelector("#coverBtn")) t.appendChild(createBtn());
};

addBtn();
const parent = getTitle().parentElement;
if(parent){
new MutationObserver(()=>{ !getTitle().querySelector("#coverBtn") && addBtn(); })
.observe(parent, {childList:true, subtree:true});
}
setInterval(addBtn, 1000);
})();
长期地址
遇到问题?请前往 GitHub 提 Issues。