您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
B站新版顶栏中加回“稍后再看”的按钮
当前为
// ==UserScript== // @id BilibiliWatchlaterButton@Laster2800 // @name B站“稍后再看”按钮 // @version 1.1 // @namespace laster2800 // @author Laster2800 // @description B站新版顶栏中加回“稍后再看”的按钮 // @include *://www.bilibili.com/* // @include *://t.bilibili.com/ // @include *://t.bilibili.com/?spm_id_from* // @run-at document-end // ==/UserScript== (function() { executeAfterElementLoaded('.user-con.signin', null, 100, 5000, addWatchlater) })(); /** * 在条件满足后执行操作 * * @param {Function} condition 指定条件,当 condition() 返回的 result 为真值时执行 callback(result) * @param {string} stopCondition 指定终止条件,当 stopCondition() 返回的 stopResult 为真值时终止检测 * @param {number} interval 检测 condition 和 stopCondition 时间间隔(单位:ms) * @param {number} timeout 当检测时间超出该时间后,终止检测(单位:ms) * @param {Function} callback 当条件通过时执行 callback(result) */ function executeAfterConditionPass(condition, stopCondition, interval, timeout, callback) { var cnt = 0 var maxCnt = timeout / interval var tid = setInterval(() => { var result = condition() var stopResult = stopCondition ? stopCondition() : false if (result || stopResult || ++cnt >= maxCnt) { clearInterval(tid) } result && callback(result) }, interval) } /** * 在元素加载完成后执行操作 * * @param {string} selector 该选择器指定一个元素 element,当这个元素加载成功时执行 callback(element) * @param {string} stopSelector 该选择器指定一个元素 stopElement,当这个元素加载成功时终止检测 * @param {number} interval 检测 element 和 stopElement 是否加载成功的时间间隔(单位:ms) * @param {number} timeout 当检测时间超出该时间后,终止检测(单位:ms) * @param {Function} callback 当 element 加载成功时执行 callback(element) */ function executeAfterElementLoaded(selector, stopSelector, interval, timeout, callback) { var condition = () => document.querySelector(selector) var stopCondition = stopSelector ? () => document.querySelector(stopSelector) : null executeAfterConditionPass(condition, stopCondition, interval, timeout, callback) } function addWatchlater(header) { if (header) { var collect = header.children[4] var watchlater = header.children[6].cloneNode(true) var link = watchlater.firstChild link.href = 'https://www.bilibili.com/watchlater/#/list' var text = link.firstChild text.innerText = '稍后再看' header.insertBefore(watchlater, collect) // 鼠标移动到“稍后再看”按钮上时,以 Tooltip 形式显示“稍后再看”列表 var watchlaterPanelSelector = '[role=tooltip][aria-hidden=false] .tabs-panel [title=稍后再看]' var dispVue = collect.firstChild.__vue__ watchlater.onmouseover = () => { // 确保原列表完全消失后再显示,避免从“收藏”移动到“稍后再看”时列表反而消失的问题 executeAfterConditionPass(() => !document.querySelector(watchlaterPanelSelector), null, 10, 500, () => { dispVue.showPopper = true executeAfterElementLoaded(watchlaterPanelSelector, null, 50, 1500, watchlaterPanel => { watchlaterPanel.parentNode.click() }) }) } // 鼠标从“稍后再看”离开时关闭列表,但移动到“收藏”上面时不关闭 collect.onmouseover = () => { collect.mouseOver = true } collect.onmouseleave = () => { collect.mouseOver = false } watchlater.onmouseleave = () => { // 要留出足够空间让 collect.mouseOver 变化 // 但有时候还是会闪,毕竟常规方式估计是无法阻止鼠标移动到“收藏”上时的 Vue 事件 setTimeout(() => { if (!collect.mouseOver) { dispVue.showPopper = false } }, 100) } } }