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
  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.  
  12. (function () {
  13. 'use strict';
  14. let totalSum = 0;
  15. let totalCount = 0;
  16. let totalRank = 0;
  17. let rankCount = 0;
  18. function calculateAverage() {
  19. const browserFullElements = document.querySelectorAll('.browserFull');
  20. totalSum = 0;
  21. totalCount = 0;
  22. const rankElements = document.querySelectorAll('.rank');
  23. totalRank = 0;
  24. rankCount = 0;
  25. browserFullElements.forEach(browserFullElement => {
  26. const liElements = browserFullElement.querySelectorAll('li');
  27. liElements.forEach(liElement => {
  28. const rateInfoElement = liElement.querySelector('.rateInfo');
  29. if (rateInfoElement) {
  30. const fadeElement = rateInfoElement.querySelector('.fade');
  31. if (fadeElement) {
  32. const value = parseFloat(fadeElement.textContent);
  33. if (!isNaN(value)) {
  34. totalSum += value;
  35. totalCount++;
  36. }
  37. }
  38. }
  39. });
  40. });
  41. rankElements.forEach(rankElement => {
  42. const smallElement = rankElement.querySelector('small');
  43. if (smallElement) {
  44. const rankText = rankElement.textContent.replace('Rank ', '').trim();
  45. const rankValue = parseInt(rankText);
  46. if (!isNaN(rankValue)) {
  47. totalRank += rankValue;
  48. rankCount++;
  49. }
  50. }
  51. });
  52. return {
  53. avgRating: totalCount === 0 ? 0 : totalSum / totalCount,
  54. avgRank: rankCount === 0 ? 0 : totalRank / rankCount
  55. };
  56. }
  57. function updateDisplay() {
  58. const {avgRating, avgRank} = calculateAverage();
  59. const averageLi = document.querySelector('#averageValue');
  60. const rankAverageLi = document.querySelector('#rankAverage');
  61. const totalCountSpan = document.querySelector('#totalCount');
  62. const rankCountSpan = document.querySelector('#rankCount');
  63. if (averageLi) {
  64. averageLi.textContent = avgRating.toFixed(4);
  65. }
  66. if (rankAverageLi) {
  67. rankAverageLi.textContent = avgRank.toFixed(4);
  68. }
  69. if (totalCountSpan) {
  70. totalCountSpan.textContent = totalCount;
  71. }
  72. if (rankCountSpan) {
  73. rankCountSpan.textContent = rankCount;
  74. }
  75. }
  76. function createFilterButtons() {
  77. const subjectFilterElement = document.querySelector('.subjectFilter');
  78. if (subjectFilterElement) {
  79. const groupedUL = document.createElement('ul');
  80. groupedUL.className = 'grouped clearit';
  81. const titleLi = document.createElement('li');
  82. titleLi.classList.add('title');
  83. titleLi.innerHTML = '<span>当前页面统计信息</span>';
  84. const averageLi = document.createElement('li');
  85. averageLi.innerHTML = `<span>评分平均值: <span id="averageValue">${ calculateAverage().avgRating.toFixed(4) }</span></span>`;
  86. const rankAverageLi = document.createElement('li');
  87. rankAverageLi.innerHTML = `<span>排名平均值: <span id="rankAverage">${ calculateAverage().avgRank.toFixed(4) }</span></span>`;
  88. const totalCountLi = document.createElement('li');
  89. totalCountLi.innerHTML = `<span>评分条目数: <span id="totalCount">${ totalCount }</span></span>`;
  90. const rankCountLi = document.createElement('li');
  91. rankCountLi.innerHTML = `<span>排名条目数: <span id="rankCount">${ rankCount }</span></span>`;
  92. groupedUL.appendChild(titleLi);
  93. groupedUL.appendChild(averageLi);
  94. groupedUL.appendChild(totalCountLi);
  95. groupedUL.appendChild(rankAverageLi);
  96. groupedUL.appendChild(rankCountLi);
  97. subjectFilterElement.appendChild(groupedUL);
  98. }
  99. }
  100. createFilterButtons();
  101. const observer = new MutationObserver(updateDisplay);
  102. observer.observe(document.body, {
  103. subtree: true,
  104. childList: true,
  105. attributes: true,
  106. attributeFilter: ['class']
  107. });
  108. }());

QingJ © 2025

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