在视频详情页追加视频封面链接
当前为
// ==UserScript==
// @name Bilibili视频详情页追加视频封面链接
// @name:zh-CN Bilibili视频详情页追加视频封面链接
// @name:en Add video cover link to Bilibili video detail page
// @namespace http://tampermonkey.net/
// @version 0.0.1
// @description 在视频详情页追加视频封面链接
// @description:en Add video cover link to video detail page
// @author aspen138
// @match *://www.bilibili.com/video/*
// @match *://www.bilibili.com/*
// @match *://www.bilibili.com
// @match *://search.bilibili.com/*
// @icon https://www.bilibili.com/favicon.ico
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_notification
// @grant GM_info
// @grant window.onurlchange
// @license MIT
// @sandbox JavaScript
// ==/UserScript==
// ↓↓↓↓↓↓↓↓↓模板,建议直接复制 //
// 自定义 urlchange 事件(用来监听 URL 变化)
function addUrlChangeEvent() {
history.pushState = ( f => function pushState(){
var ret = f.apply(this, arguments);
window.dispatchEvent(new Event('pushstate'));
window.dispatchEvent(new Event('urlchange'));
return ret;
})(history.pushState);
history.replaceState = ( f => function replaceState(){
var ret = f.apply(this, arguments);
window.dispatchEvent(new Event('replacestate'));
window.dispatchEvent(new Event('urlchange'));
return ret;
})(history.replaceState);
window.addEventListener('popstate',()=>{
window.dispatchEvent(new Event('urlchange'))
});
}
var menu_ALL = [
['menu_isEnableAppendCoverLink', '默认追加视频封面链接', '默认追加视频封面链接', false]
], menu_ID = [];
for (let i=0;i<menu_ALL.length;i++){ // 如果读取到的值为 null 就写入默认值
if (GM_getValue(menu_ALL[i][0]) == null){GM_setValue(menu_ALL[i][0], menu_ALL[i][3])};
}
// 注册(不可用)脚本菜单
function registerMenuCommand() {
if (menu_ID.length >= menu_ALL.length){ // 如果菜单ID数组长度大于等于菜单数组长度,说明不是首次添加菜单,需要卸载所有脚本菜单
for (let i=0;i<menu_ID.length;i++){
GM_unregisterMenuCommand(menu_ID[i]);
}
}
for (let i=0;i<menu_ALL.length;i++){ // 循环注册(不可用)脚本菜单
menu_ALL[i][3] = GM_getValue(menu_ALL[i][0]);
menu_ID[i] = GM_registerMenuCommand(`${menu_ALL[i][3]?'✅':'❌'} ${menu_ALL[i][1]}`, function(){menu_switch(`${menu_ALL[i][3]}`,`${menu_ALL[i][0]}`,`${menu_ALL[i][2]}`)});
}
}
// 菜单开关
function menu_switch(menu_status, Name, Tips) {
if (menu_status == 'true'){
GM_setValue(`${Name}`, false);
GM_notification({text: `已关闭 [${Tips}] 功能\n(点击刷新网页后生效)`, timeout: 3500, onclick: function(){location.reload();}});
}else{
GM_setValue(`${Name}`, true);
GM_notification({text: `已开启 [${Tips}] 功能\n(点击刷新网页后生效)`, timeout: 3500, onclick: function(){location.reload();}});
}
registerMenuCommand(); // 重新注册(不可用)脚本菜单
};
// 返回菜单值
function menu_value(menuName) {
for (let menu of menu_ALL) {
if (menu[0] == menuName) {
return menu[3]
}
}
}
for (let i=0;i<menu_ALL.length;i++){ // 如果读取到的值为 null 就写入默认值
if (GM_getValue(menu_ALL[i][0]) == null){GM_setValue(menu_ALL[i][0], menu_ALL[i][3])};
}
registerMenuCommand();
if (window.onurlchange === undefined) {addUrlChangeEvent();} // Tampermonkey v4.11 版本添加的 onurlchange 事件 grant,可以监控 pjax 等网页的 URL 变化
// ↑↑↑↑↑↑↑↑↑↑↑↑模板,建议直接复制 //
function appendCoverLink() {
let BVid = '';
const match1 = location.pathname.match(/BV[^/]*/);
if (match1) {
BVid = match1[0];
} else {
// console.error("No match found");
}
// Select the parent container where the new element will be appended
const parentContainer = document.querySelector(`.video-info-detail-list.video-info-detail-content:not(.${BVid}modified)`);
if (!parentContainer) {
console.warn('Parent container not found. Ensure the selector is correct.');
return;
}
// Ensure the link is only appended once
const existingCoverLink = parentContainer.querySelector(' .cover-link');
if (existingCoverLink) {
existingCoverLink.remove();
}
// Extract the cover image URL from the document head
const imageMetaTag = document.head.querySelector('[itemprop="image"]');
if (!imageMetaTag) {
console.warn('Image meta tag with [itemprop="image"] not found.');
return;
}
// Create the new container div with appropriate classes
const coverItem = document.createElement('div');
coverItem.classList.add('cover-item', 'item');
// Create the SVG icon (optional)
const coverIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
coverIcon.setAttribute('class', 'cover-icon');
coverIcon.setAttribute('style', 'width:20px;height:20px;');
coverIcon.setAttribute('viewBox', '0 0 20 20');
coverIcon.setAttribute('width', '20');
coverIcon.setAttribute('height', '20');
// Example SVG path
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', 'M10 0 L20 20 L0 20 Z');
path.setAttribute('fill', 'currentColor');
coverIcon.appendChild(path);
// Create the link element
const coverLink = document.createElement('a');
coverLink.setAttribute('target', '_blank');
coverLink.setAttribute('rel', 'noopener noreferrer');
coverLink.classList.add('cover-link');
coverLink.setAttribute('title', 'You may need F5 refresh to get consistent cover');
// Create the text node
const linkText = document.createElement('span');
linkText.classList.add('cover-text');
linkText.textContent = 'Cover';
// Assemble the link
coverLink.appendChild(coverIcon);
coverLink.appendChild(linkText);
// Append the link to the new item container
coverItem.appendChild(coverLink);
setTimeout(() => {
BVid = 'default';
const match = location.pathname.match(/BV[^/]*/);
if (match) {
BVid = match[0];
} else {
// console.error("No match found");
}
// Mark this container as modified
parentContainer.classList.add(BVid + 'modified');
// Replace 'http' with 'https' if necessary
const coverImgUrl =
'https://' + imageMetaTag.getAttribute('content').replace('http', 'https').split('@')[0];
console.log("coverImgUrl=", coverImgUrl);
coverLink.setAttribute('href', coverImgUrl);
// Ensure the link is only appended once
const existingCoverLink = parentContainer.querySelector('.cover-link');
if (existingCoverLink) {
existingCoverLink.remove();
}
parentContainer.append(coverLink);
console.log('Cover link appended successfully.');
}, 2*1000);
}
(function () {
// Retrieve the current setting, default to false
let isEnableAppendCoverLink = GM_getValue('menu_isEnableAppendCoverLink', false);
if (isEnableAppendCoverLink){
const checkIntervalAppendCoverLink = setInterval(()=>appendCoverLink(), 300);
// Cleanup after 30 seconds
setTimeout(() => {
clearInterval(checkIntervalAppendCoverLink);
observer.disconnect(); // Optionally disconnect the observer after cleanup
}, 30*1000);
}
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址