VNDB Card/Grid view buttons for producer page

Add buttons «Go to Card view» and «Go to Grid view» on https://vndb.org/PID pages.

  1. // ==UserScript==
  2. // @name VNDB Card/Grid view buttons for producer page
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Add buttons «Go to Card view» and «Go to Grid view» on https://vndb.org/PID pages.
  6. // @author mleaqaavwv
  7. // @match https://vndb.org/p*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15.  
  16. const suffixAlphabet = [
  17. ...Array.from({length: 10}, (_, i) => String(i)),
  18. ...Array.from({length: 26}, (_, i) => String.fromCharCode(97 + i)),
  19. ...Array.from({length: 26}, (_, i) => String.fromCharCode(65 + i)),
  20. '_', '-'
  21. ];
  22.  
  23. function encodeNumber(n) {
  24. if (n <= 9) {
  25. return String(n);
  26. }
  27. if (n <= 35) {
  28. return String.fromCharCode(97 + (n - 10));
  29. }
  30. if (n <= 48) {
  31. return String.fromCharCode(65 + (n - 36));
  32. }
  33.  
  34. let offset = n - 49;
  35. const base = suffixAlphabet.length; // 64
  36.  
  37.  
  38. const block1 = 10 * base;
  39. if (offset < block1) {
  40. const prefix = String.fromCharCode(78 + Math.floor(offset / base)); // 'N' → 78
  41. return prefix + suffixAlphabet[offset % base];
  42. }
  43.  
  44. offset -= block1;
  45.  
  46.  
  47. const block2 = base * base;
  48. if (offset < block2) {
  49. const d1 = Math.floor(offset / base);
  50. const d2 = offset % base;
  51. return 'X' + suffixAlphabet[d1] + suffixAlphabet[d2];
  52. }
  53.  
  54. offset -= block2;
  55.  
  56.  
  57. const d1 = Math.floor(offset / (base * base));
  58. const d2 = Math.floor(offset / base) % base;
  59. const d3 = offset % base;
  60. return 'Y' + suffixAlphabet[d1] + suffixAlphabet[d2] + suffixAlphabet[d3];
  61. }
  62.  
  63.  
  64. const match = window.location.pathname.match(/^\/p(\d+)/);
  65. if (!match) return;
  66. const vnId = parseInt(match[1], 10);
  67. const enc = encodeNumber(vnId);
  68.  
  69.  
  70. const cardUrl = `https://vndb.org/v?f=12N18N6830${enc}N6830${enc}&s=221`;
  71. const gridUrl = `https://vndb.org/v?f=12N18N6830${enc}N6830${enc}&p=1&s=222`;
  72.  
  73.  
  74. const container = document.createElement('div');
  75. Object.assign(container.style, {
  76. position: 'fixed',
  77. top: '10px',
  78. right: '10px',
  79. display: 'flex',
  80. flexDirection: 'column',
  81. gap: '5px',
  82. zIndex: '9999'
  83. });
  84.  
  85.  
  86. function makeButton(label, href) {
  87. const btn = document.createElement('a');
  88. btn.textContent = label;
  89. btn.href = href;
  90. btn.style.cssText = `
  91. display: inline-block;
  92. padding: 6px 12px;
  93. background: #4CAF50;
  94. color: #fff;
  95. border-radius: 4px;
  96. text-decoration: none;
  97. font-weight: bold;
  98. font-size: 0.9em;
  99. text-align: center;
  100. `;
  101.  
  102. btn.addEventListener('mouseover', function() {
  103. btn.style.background = '#45A049';
  104. });
  105. btn.addEventListener('mouseout', function() {
  106. btn.style.background = '#4CAF50';
  107. });
  108. return btn;
  109. }
  110.  
  111. container.appendChild(makeButton('Go to Card view', cardUrl));
  112. container.appendChild(makeButton('Go to Grid view', gridUrl));
  113.  
  114. document.body.appendChild(container);
  115. })();

QingJ © 2025

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