Bilibili 哔哩哔哩查看原图

方便在B站内查看各种图片的原图,支持动态、专栏

Инсталирай този скрипт?
Препоръчано от автора

Може да харесате и Bilibili 哔哩哔哩视频点踩.

Инсталирай този скрипт
  1. // ==UserScript==
  2. // @name Bilibili 哔哩哔哩查看原图
  3. // @icon https://t.bilibili.com/favicon.ico
  4. // @namespace https://lolico.moe/
  5. // @version 3.1.0
  6. // @description 方便在B站内查看各种图片的原图,支持动态、专栏
  7. // @author Jindai Kirin
  8. // @match https://t.bilibili.com/*
  9. // @match https://space.bilibili.com/*
  10. // @match https://www.bilibili.com/opus/*
  11. // @match https://www.bilibili.com/read/*
  12. // @license GPL-3.0
  13. // @grant GM_addStyle
  14. // @grant GM_download
  15. // @run-at document-end
  16. // @require https://code.bdstatic.com/npm/jquery@3.6.0/dist/jquery.min.js
  17. // ==/UserScript==
  18.  
  19. (function () {
  20. 'use strict';
  21.  
  22. const DOWNLOAD_ICON =
  23. '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" style="width: 16px; height: 16px; transform: none !important;" fill="currentColor"><path d="M5,20h14v-2H5V20z M19,9h-4V3H9v6H5l7,7L19,9z"/></svg>';
  24.  
  25. const css = ([style]) => GM_addStyle(style);
  26. const last = arr => arr[arr.length - 1];
  27.  
  28. if (
  29. location.hostname === 't.bilibili.com' ||
  30. location.hostname === 'space.bilibili.com' ||
  31. (location.hostname === 'www.bilibili.com' && location.pathname.startsWith('/opus/'))
  32. ) {
  33. css`
  34. .bili-album__watch__control__option.ccw-rotation svg {
  35. transform: scaleX(-1);
  36. }
  37. @media screen and (max-width: 1319px) {
  38. .bili-album__watch__control__option {
  39. padding: 0 12px !important;
  40. }
  41. }
  42. `;
  43. // 添加下载原图按钮
  44. document.addEventListener(
  45. 'click',
  46. async ({ target }) => {
  47. const $target = $(target);
  48. if (
  49. $target.hasClass('bili-album__preview__picture__img') ||
  50. $target.parent().hasClass('b-img__inner')
  51. ) {
  52. const $album = $target.parents('.bili-album');
  53. const $btn = await waitBtn(
  54. $album,
  55. '.bili-album__watch__control__option.full-screen',
  56. '.bili-album__watch'
  57. );
  58. if ($btn.length > 1) return;
  59. const $newBtn = $($btn.prop('outerHTML').replace('查看大图', '下载原图'));
  60. $newBtn.find('svg').replaceWith(DOWNLOAD_ICON);
  61. $newBtn.on('click', () => {
  62. const url = $album
  63. .find('.bili-album__watch__content img')
  64. .attr('src')
  65. .replace(/@.*$/, '')
  66. .replace(/^\/*/, 'https://');
  67. if (!url) {
  68. alert('找不到图片地址');
  69. return;
  70. }
  71. const name = last(url.split('/'));
  72. GM_download(url, name);
  73. });
  74. $btn.after($newBtn);
  75. }
  76. },
  77. { capture: true }
  78. );
  79. } else if (location.hostname === 'www.bilibili.com' && location.pathname.startsWith('/read/')) {
  80. css`
  81. img.normal-img,
  82. .card-image__image {
  83. cursor: pointer;
  84. }
  85. `;
  86. // 专栏图片点击打开原图
  87. $(document.body).on('click', 'img.normal-img', function () {
  88. window.open($(this).attr('src').replace(/@.*?$/, ''));
  89. });
  90. // 专栏头图点击打开原图
  91. $(document.body).on('click', '.card-image__image', function () {
  92. window.open(
  93. $(this)
  94. .css('background-image')
  95. .replace(/^url\(["']?/, '')
  96. .replace(/["']?\)$/, '')
  97. .replace(/@.*?$/, ''),
  98. '_blank'
  99. );
  100. });
  101. }
  102.  
  103. /**
  104. * 等待查看大图按钮出现
  105. * @param {JQuery<HTMLElement>} $el
  106. * @param {string} btnSelector
  107. * @param {string} waitNodeSelector
  108. * @returns {JQuery<HTMLElement>}
  109. */
  110. function waitBtn($el, btnSelector, waitNodeSelector) {
  111. return new Promise(resolve => {
  112. const $btn = $el.find(btnSelector);
  113. if ($btn.length > 0) {
  114. resolve($btn);
  115. return;
  116. }
  117. new MutationObserver((mutations, self) => {
  118. mutations.forEach(({ addedNodes }) => {
  119. if (addedNodes.length && $(addedNodes[0]).is(waitNodeSelector)) {
  120. self.disconnect();
  121. resolve($el.find(btnSelector));
  122. }
  123. });
  124. }).observe($el[0], { childList: true });
  125. });
  126. }
  127. })();