PersonPageStats

show avg ratings and rankings on a person's page on bangumi

  1. // ==UserScript==
  2. // @name PersonPageStats
  3. // @namespace https://jirehlov.com
  4. // @version 0.1.1
  5. // @description show avg ratings and rankings on a person's page on bangumi
  6. // @author Jirehlov
  7. // @include /^https?:\/\/(bgm\.tv|bangumi\.tv|chii\.in)\/person\/\d+(?!\/works\/voice)\/works/
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11. (function () {
  12. "use strict";
  13. let totalSum = 0;
  14. let totalCount = 0;
  15. let totalRank = 0;
  16. let rankCount = 0;
  17. function calculateAverage() {
  18. const browserFullElements = document.querySelectorAll(".browserFull");
  19. totalSum = 0;
  20. totalCount = 0;
  21. totalRank = 0;
  22. rankCount = 0;
  23. browserFullElements.forEach(browserFullElement => {
  24. const liElements = browserFullElement.querySelectorAll("li");
  25. liElements.forEach(liElement => {
  26. const rateInfoElement = liElement.querySelector(".rateInfo");
  27. if (rateInfoElement) {
  28. const fadeElement = rateInfoElement.querySelector(".fade");
  29. if (fadeElement) {
  30. const value = parseFloat(fadeElement.textContent);
  31. if (!isNaN(value)) {
  32. totalSum += value;
  33. totalCount++;
  34. }
  35. }
  36. }
  37. });
  38. });
  39. const rankElements = document.querySelectorAll(".rank");
  40. rankElements.forEach(rankElement => {
  41. const smallElement = rankElement.querySelector("small");
  42. if (smallElement) {
  43. const rankText = rankElement.textContent.replace("Rank ", "").trim();
  44. const rankValue = parseInt(rankText);
  45. if (!isNaN(rankValue)) {
  46. totalRank += rankValue;
  47. rankCount++;
  48. }
  49. }
  50. });
  51. return {
  52. avgRating: totalCount === 0 ? 0 : totalSum / totalCount,
  53. avgRank: rankCount === 0 ? 0 : totalRank / rankCount
  54. };
  55. }
  56. function updateDisplay() {
  57. const {avgRating, avgRank} = calculateAverage();
  58. const averageLi = document.querySelector("#averageValue");
  59. const rankAverageLi = document.querySelector("#rankAverage");
  60. const totalCountSpan = document.querySelector("#totalCount");
  61. const rankCountSpan = document.querySelector("#rankCount");
  62. if (averageLi)
  63. averageLi.textContent = avgRating.toFixed(4);
  64. if (rankAverageLi)
  65. rankAverageLi.textContent = avgRank.toFixed(4);
  66. if (totalCountSpan)
  67. totalCountSpan.textContent = totalCount;
  68. if (rankCountSpan)
  69. rankCountSpan.textContent = rankCount;
  70. }
  71. function createFilterButtons() {
  72. const subjectFilterElement = document.querySelector(".subjectFilter");
  73. if (subjectFilterElement) {
  74. const groupedUL = document.createElement("ul");
  75. groupedUL.className = "grouped clearit";
  76. const titleLi = document.createElement("li");
  77. titleLi.classList.add("title");
  78. titleLi.innerHTML = "<span>当前页面统计信息</span>";
  79. const averageLi = document.createElement("li");
  80. averageLi.innerHTML = `<span>评分平均值: <span id="averageValue">${ calculateAverage().avgRating.toFixed(4) }</span></span>`;
  81. const totalCountLi = document.createElement("li");
  82. totalCountLi.innerHTML = `<span>评分条目数: <span id="totalCount">${ totalCount }</span></span>`;
  83. const rankAverageLi = document.createElement("li");
  84. rankAverageLi.innerHTML = `<span>排名平均值: <span id="rankAverage">${ calculateAverage().avgRank.toFixed(4) }</span></span>`;
  85. const rankCountLi = document.createElement("li");
  86. rankCountLi.innerHTML = `<span>排名条目数: <span id="rankCount">${ rankCount }</span></span>`;
  87. groupedUL.appendChild(titleLi);
  88. groupedUL.appendChild(averageLi);
  89. groupedUL.appendChild(totalCountLi);
  90. groupedUL.appendChild(rankAverageLi);
  91. groupedUL.appendChild(rankCountLi);
  92. subjectFilterElement.appendChild(groupedUL);
  93. }
  94. }
  95. createFilterButtons();
  96. updateDisplay();
  97. const observer = new MutationObserver(() => {
  98. observer.disconnect();
  99. updateDisplay();
  100. observer.observe(document.body, {
  101. subtree: true,
  102. childList: true,
  103. attributes: true,
  104. attributeFilter: ["class"]
  105. });
  106. });
  107. observer.observe(document.body, {
  108. subtree: true,
  109. childList: true,
  110. attributes: true,
  111. attributeFilter: ["class"]
  112. });
  113. }());

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址