// ==UserScript==
// @name B站显示点赞率、投币率、收藏率
// @namespace http://tampermonkey.net/
// @version 1.0.2
// @description 显示b站 | bilibili | 哔哩哔哩 点赞率、投币率、收藏率
// @license MIT
// @author 魂hp
// @website https://space.bilibili.com/474989498
// @match *.bilibili.com/video/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com
// @grant GM.addStyle
// @grant unsafeWindow
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @downloadURL none
// ==/UserScript==
(function () {
"use strict";
if (!(unsafeWindow?.__INITIAL_STATE__?.videoData?.stat?.view)) {
return;
}
// representation字段表示比率的表示形式,该字段为 fractions 时表示为分数,该字段为 percentage 时表示为百分比
let representation = GM_getValue("representation")
if (representation == null) {
GM_setValue("representation", "fractions")
representation = "fractions"
}
const isFractions = representation == "fractions"
// 注册脚本菜单以实现两种表示方式的相互转换
GM_registerMenuCommand(
"切换比率的表示方式(百分比和分数)",
function () {
representation = representation == "fractions" ? "percentage" : "fractions"
GM_setValue("representation", representation)
unsafeWindow.location.reload()
}, {
autoClose: false,
}
);
// 修改样式
GM.addStyle(`
.video-toolbar-left-item{
width:auto !important;
}
.toolbar-left-item-wrap{
display:flex !important;
margin-right: 12px !important;
}
.video-share-info{
width:auto !important;
max-width:90px;
}
.video-share-info-text{
position: relative !important;
}
`);
// 百分比形式会占用更大的空间,需要额外添加样式
if (!isFractions) {
GM.addStyle(`
.video-toolbar-item-icon {
margin-right:6px !important;
}
.toolbar-right-note{
margin-right:5px !important;
}
.toolbar-right-ai{
margin-right:12px !important;
}
`);
}
class videoData {
videoStat = {
view: 0,
like: 0,
coin: 0,
favorite: 0,
share: 0
};
constructor() {
this.initVideoStat();
}
initVideoStat() {
for (let key in this.videoStat) {
this.videoStat[key] = unsafeWindow.__INITIAL_STATE__.videoData.stat[key];
}
}
// 计算点赞率、投币率、收藏率、转发率,并获取对应的颜色
getRateAndColor(nameStr) {
let res = {
rate: 0,
color: "#222"
};
if (!(nameStr in this.videoStat)) {
return res;
}
let num = this.videoStat.view / this.videoStat[nameStr];
if (num == Infinity) {
return res;
}
// 当比率大于十分之一设置为橘色,大于二十五分之一设置为紫色,其他则设置为黑色(如果需要添加其他的范围对应的颜色或修改颜色可以改这部分)
if (num <= 10) {
if (isFractions) {
res.rate = num.toFixed(2);
} else {
res.rate = (this.videoStat[nameStr] * 100 / this.videoStat.view).toFixed(2)
}
res.color = "DarkOrange";
} else if (num <= 25) {
if (isFractions) {
res.rate = num.toFixed(1);
} else {
res.rate = (this.videoStat[nameStr] * 100 / this.videoStat.view).toFixed(2)
}
res.color = "#db03fc";
} else {
if (isFractions) {
res.rate = num.toFixed(0);
} else {
res.rate = (this.videoStat[nameStr] * 100 / this.videoStat.view).toFixed(2)
}
}
return res;
}
}
const vData = new videoData();
//添加元素
const div = {
like: {},
coin: {},
favorite: {},
share: {}
};
for (let e in div) {
div[e] = document.createElement("div");
div[e].style.setProperty("display", "flex")
div[e].style.setProperty("align-items", "center")
if (isFractions) {
div[e].innerHTML = `
≈
`;
} else {
div[e].innerHTML = `
≈
%
`
}
}
// 更新数据
function updateRate() {
for (let e in div) {
let data = div[e].querySelector("#data");
let rateAndColor = vData.getRateAndColor(e);
data.style.color = rateAndColor.color;
data.textContent = rateAndColor.rate;
}
}
updateRate();
new MutationObserver(function (mutationsList) {
for (let mutation of mutationsList) {
if (mutation.type === "attributes") {
document
.querySelector(".video-like")
.parentNode.appendChild(div.like);
document
.querySelector(".video-coin")
.parentNode.appendChild(div.coin);
document
.querySelector(".video-fav")
.parentNode.appendChild(div.favorite);
document
.querySelector(".video-share-wrap")
.parentNode.appendChild(div.share);
}
}
}).observe(document.querySelector(".toolbar-left-item-wrap"), {
attributes: true,
});
new MutationObserver(function (mutationsList) {
for (let mutation of mutationsList) {
if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
vData.initVideoStat();
updateRate();
}
}
}).observe(document.querySelector(".video-fav-info"), {
childList: true,
});
})();