Skip to content

Instantly share code, notes, and snippets.

@Qixingchen
Last active April 8, 2026 13:01
Show Gist options
  • Select an option

  • Save Qixingchen/94c69949cd90f4858ebb7d200c44e135 to your computer and use it in GitHub Desktop.

Select an option

Save Qixingchen/94c69949cd90f4858ebb7d200c44e135 to your computer and use it in GitHub Desktop.
隐藏B站动态短视频及充电视频
// ==UserScript==
// @name 隐藏B站动态短视频
// @namespace http://tampermonkey.net/
// @version 1.2
// @description 隐藏B站动态页面中视频长度小于1分钟的条目,以及充电专属视频
// @author qixingchen
// @match https://t.bilibili.com/*
// @icon https://www.bilibili.com/favicon.ico
// @grant none
// @run-at document-idle
// @updateURL https://gist.github.com/Qixingchen/94c69949cd90f4858ebb7d200c44e135/raw/hide_short_videos.user.js
// @downloadURL https://gist.github.com/Qixingchen/94c69949cd90f4858ebb7d200c44e135/raw/hide_short_videos.user.js
// ==/UserScript==
(function() {
'use strict';
// 配置:最小视频时长(秒),小于此值将被隐藏
const MIN_DURATION_SECONDS = 60;
let hiddenCount = 0;
let hiddenChargeCount = 0;
// 解析时长字符串(格式如 "04:09", "00:16", "1:23:45")
function parseDuration(durationStr) {
const parts = durationStr.split(':').map(Number);
if (parts.length === 2) {
// MM:SS 格式
return parts[0] * 60 + parts[1];
} else if (parts.length === 3) {
// HH:MM:SS 格式
return parts[0] * 3600 + parts[1] * 60 + parts[2];
}
return 0;
}
// 格式化秒数为可读字符串
function formatDuration(seconds) {
if (seconds < 60) {
return `${seconds}秒`;
} else if (seconds < 3600) {
return `${Math.floor(seconds / 60)}${seconds % 60}秒`;
} else {
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
return `${h}小时${m}分`;
}
}
// 获取当前屏幕顶部显示的是第几条可见动态
function getTopVisibleIndex() {
const visibleItems = Array.from(document.querySelectorAll('.bili-dyn-list__item:not([style*="display: none"])'));
for (let i = 0; i < visibleItems.length; i++) {
const rect = visibleItems[i].getBoundingClientRect();
// 找到第一个底部在视口内的条目
if (rect.bottom > 0) {
return i + 1;
}
}
return 1;
}
// 显示统计信息
function showStats() {
let statsEl = document.getElementById('hide-short-video-stats');
if (!statsEl) {
statsEl = document.createElement('div');
statsEl.id = 'hide-short-video-stats';
statsEl.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
background: rgba(0, 161, 214, 0.9);
color: white;
padding: 10px 15px;
border-radius: 8px;
font-size: 14px;
z-index: 10000;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
cursor: pointer;
transition: opacity 0.3s;
`;
statsEl.title = '点击隐藏此提示';
statsEl.onclick = () => {
statsEl.style.opacity = '0';
setTimeout(() => statsEl.remove(), 300);
};
document.body.appendChild(statsEl);
}
if (hiddenCount > 0 || hiddenChargeCount > 0) {
const visibleCount = document.querySelectorAll('.bili-dyn-list__item:not([style*="display: none"])').length;
const topIndex = getTopVisibleIndex();
let line1 = `第 ${topIndex}/${visibleCount} 条动态`;
let line2 = '';
if (hiddenCount > 0) {
line2 += `已隐藏 ${hiddenCount} 个短视频(<${formatDuration(MIN_DURATION_SECONDS)})`;
}
if (hiddenChargeCount > 0) {
if (hiddenCount > 0) line2 += ',';
line2 += `${hiddenChargeCount} 个充电专属`;
}
statsEl.innerHTML = line1 + '<br>' + line2;
statsEl.style.display = 'block';
} else {
statsEl.style.display = 'none';
}
}
// 检查是否为充电专属视频
function isChargeExclusive(listItem) {
// 充电专属角标的选择器
const chargeBadges = listItem.querySelectorAll('.bili-dyn-card-video__badge, .bili-dyn-card-video__tag');
for (const badge of chargeBadges) {
const text = badge.textContent.trim();
if (text.includes('充电专属') || text.includes('充电')) {
return true;
}
}
// 也检查其他可能的角标位置
const allBadges = listItem.querySelectorAll('[class*="badge"], [class*="tag"]');
for (const badge of allBadges) {
const text = badge.textContent.trim();
if (text === '充电专属' || text === '充电') {
return true;
}
}
return false;
}
// 隐藏短视频条目和充电专属视频
function hideShortVideos() {
// 查找所有视频时长元素
const durationElements = document.querySelectorAll('.duration-time');
let newHidden = 0;
let newChargeHidden = 0;
// 处理所有动态条目
const listItems = document.querySelectorAll('.bili-dyn-list__item');
listItems.forEach(listItem => {
// 跳过已处理的元素
if (listItem.dataset.hideProcessed) return;
listItem.dataset.hideProcessed = 'true';
// 检查是否为充电专属
if (isChargeExclusive(listItem)) {
if (listItem.style.display !== 'none') {
listItem.style.display = 'none';
listItem.dataset.hiddenByScript = 'true';
listItem.dataset.hiddenReason = 'charge';
newChargeHidden++;
console.log(`[隐藏短视频] 已隐藏充电专属视频`);
}
return;
}
// 查找时长元素
const durationEl = listItem.querySelector('.duration-time');
if (!durationEl) return;
const durationStr = durationEl.textContent.trim();
const durationSeconds = parseDuration(durationStr);
// 如果时长小于阈值,隐藏整个动态条目
if (durationSeconds > 0 && durationSeconds < MIN_DURATION_SECONDS) {
if (listItem.style.display !== 'none') {
listItem.style.display = 'none';
listItem.dataset.hiddenByScript = 'true';
listItem.dataset.hiddenReason = 'short';
newHidden++;
console.log(`[隐藏短视频] 已隐藏 ${durationStr} 的视频`);
}
}
});
if (newHidden > 0 || newChargeHidden > 0) {
hiddenCount += newHidden;
hiddenChargeCount += newChargeHidden;
showStats();
}
}
// 使用 MutationObserver 监听动态内容变化
const observer = new MutationObserver((mutations) => {
hideShortVideos();
});
// 页面加载完成后开始观察
const startObserver = () => {
const listContainer = document.querySelector('.bili-dyn-list__items');
if (listContainer) {
observer.observe(listContainer, {
childList: true,
subtree: true
});
// 初始执行一次
hideShortVideos();
} else {
// 如果容器还没加载,等待后重试
setTimeout(startObserver, 500);
}
};
// 页面加载后启动
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startObserver);
} else {
startObserver();
}
// 同时也监听整个 body 的变化,以防容器后来才出现
const bodyObserver = new MutationObserver(() => {
if (document.querySelector('.bili-dyn-list__items')) {
startObserver();
bodyObserver.disconnect();
}
});
bodyObserver.observe(document.body, { childList: true, subtree: true });
// 监听滚动事件,实时更新当前位置
let scrollTimer = null;
window.addEventListener('scroll', () => {
if (scrollTimer) clearTimeout(scrollTimer);
scrollTimer = setTimeout(() => {
if (hiddenCount > 0 || hiddenChargeCount > 0) {
showStats();
}
}, 100);
}, { passive: true });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment