图集岛侧边栏

在图集岛页面中的侧边栏显示标签、人物和链接,并具备自动隐藏和迷你边栏功能

  1. // ==UserScript==
  2. // @name 图集岛侧边栏
  3. // @namespace http://www.tujidao09.com/
  4. // @version 3.7
  5. // @description 在图集岛页面中的侧边栏显示标签、人物和链接,并具备自动隐藏和迷你边栏功能
  6. // @author William Zhou
  7. // @match *://*.jimeilu*.com/*
  8. // @match *://*.tujidao*.com/*
  9. // @match *://*.sqmuying.com/*
  10. // @include /^https?:\/\/jimeilu[0-9]*\.com\/.*$/
  11. // @include /^https?:\/\/.*\.jimeilu[0-9]*\.com\/.*$/
  12. // @include /^https?:\/\/tujidao[0-9]*\.com\/.*$/
  13. // @include /^https?:\/\/.*\.tujidao[0-9]*\.com\/.*$/
  14. // @include /^https?:\/\/sqmuying[0-9]*\.com\/.*$/
  15. // @include /^https?:\/\/.*\.sqmuying[0-9]*\.com\/.*$/
  16. // @icon https://www.apple.com.cn/v/iphone/home/bp/images/overview/compare/icon_touch_id__etlcbgeryay6_large.png
  17. // @grant GM_addStyle
  18. // ==/UserScript==
  19.  
  20. (function() {
  21. 'use strict';
  22.  
  23. let sidebarVersion = 1.0;
  24.  
  25. // 每次输出后将版本号增加 0.1
  26. sidebarVersion += 0.1;
  27. console.log(`侧边栏版本:${sidebarVersion}`);
  28.  
  29. // 创建并显示侧边栏的函数
  30. function createSidebar(tagsWithImages, tagsWithoutImages, characters, h1Links) {
  31. const sidebarContainer = document.createElement('div');
  32. sidebarContainer.id = 'sidebar-container';
  33. sidebarContainer.style.position = 'fixed';
  34. sidebarContainer.style.top = '50%';
  35. sidebarContainer.style.right = '-140px'; // 初始化位置在屏幕外
  36. sidebarContainer.style.transform = 'translateY(-50%)';
  37. sidebarContainer.style.width = '120px';
  38. sidebarContainer.style.height = '480px';
  39. sidebarContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  40. sidebarContainer.style.backdropFilter = 'blur(10px)';
  41. sidebarContainer.style.borderRadius = '8px'; // 添加8px圆角
  42. sidebarContainer.style.color = '#ffffff';
  43. sidebarContainer.style.padding = '10px';
  44. sidebarContainer.style.zIndex = '9999';
  45. sidebarContainer.style.overflowY = 'auto';
  46. sidebarContainer.style.transition = 'right 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.28) 0s'; // 添加动画效果
  47.  
  48. const tagsList = document.createElement('ul');
  49. tagsList.style.listStyle = 'none';
  50. tagsList.style.margin = '0';
  51. tagsList.style.padding = '0';
  52.  
  53. // 将带有 "[]" 的字符放在列表的前面
  54. characters.sort((a, b) => {
  55. if (a.includes('[') && a.includes(']')) {
  56. return -1;
  57. } else if (b.includes('[') && b.includes(']')) {
  58. return 1;
  59. } else {
  60. return 0;
  61. }
  62. });
  63.  
  64. characters.forEach(character => {
  65. const characterItem = document.createElement('li');
  66. const characterLink = document.createElement('a');
  67. characterLink.href = `/sousu/?s0=${character}`;
  68. characterLink.textContent = `[${character}]`;
  69. characterLink.style.color = '#ffffff';
  70. characterItem.appendChild(characterLink);
  71. tagsList.appendChild(characterItem);
  72. });
  73.  
  74. tagsWithImages.forEach(tag => {
  75. const tagItem = document.createElement('li');
  76. const tagImage = document.createElement('img');
  77. const tagLink = document.createElement('a');
  78. tagImage.src = `https://picew6d4ew.82pic.com/t/${tag.imageId}.jpg`;
  79. tagImage.style.maxWidth = '100%';
  80. tagImage.style.borderRadius = '20px'; // 添加20px圆角
  81. tagLink.href = tag.link;
  82. tagLink.textContent = tag.name;
  83. tagLink.style.color = '#ffffff';
  84. tagItem.appendChild(tagImage);
  85. tagItem.appendChild(tagLink);
  86. tagsList.appendChild(tagItem);
  87. });
  88.  
  89. tagsWithoutImages.forEach(tag => {
  90. const tagItem = document.createElement('li');
  91. const tagLink = document.createElement('a');
  92. tagLink.href = tag.link;
  93. tagLink.textContent = tag.name;
  94. tagLink.style.color = '#ffffff';
  95. tagItem.appendChild(tagLink);
  96. tagsList.appendChild(tagItem);
  97. });
  98.  
  99. h1Links.forEach(h1Link => {
  100. const h1Item = document.createElement('li');
  101. const h1LinkElement = document.createElement('a');
  102. h1LinkElement.href = `/sousu/?s0=${h1Link}`;
  103. h1LinkElement.textContent = `[${h1Link}]`;
  104. h1LinkElement.style.color = '#ffffff';
  105. h1Item.appendChild(h1LinkElement);
  106. tagsList.appendChild(h1Item);
  107. });
  108.  
  109. sidebarContainer.appendChild(tagsList);
  110. document.body.appendChild(sidebarContainer);
  111.  
  112. // 将侧边栏移动到显示位置
  113. setTimeout(() => {
  114. sidebarContainer.style.right = '0';
  115. }, 100);
  116.  
  117. // 鼠标未在侧边栏操作时,30秒后隐藏侧边栏并显示倒计时状态
  118. let timer;
  119. sidebarContainer.addEventListener('mouseleave', () => {
  120. clearTimeout(timer);
  121. timer = setTimeout(() => {
  122. sidebarContainer.style.right = '-140px';
  123. showMiniSidebar();
  124. }, 3000); // 30秒后自动隐藏侧边栏
  125. });
  126.  
  127. // 显示迷你边栏
  128. function showMiniSidebar() {
  129. const miniSidebar = document.createElement('div');
  130. miniSidebar.id = 'mini-sidebar';
  131. miniSidebar.style.position = 'fixed';
  132. miniSidebar.style.top = '50%';
  133. miniSidebar.style.right = '0';
  134. miniSidebar.style.transform = 'translateY(-50%)';
  135. miniSidebar.style.width = '8px';
  136. miniSidebar.style.height = '100px';
  137. miniSidebar.style.backgroundColor = '#17a1ff';
  138. miniSidebar.style.borderRadius = '100px'; // 添加圆角
  139. miniSidebar.style.zIndex = '9998';
  140. miniSidebar.style.cursor = 'pointer';
  141. miniSidebar.addEventListener('mouseenter', () => {
  142. sidebarContainer.style.right = '0';
  143. clearTimeout(timer);
  144. });
  145.  
  146. miniSidebar.style.backgroundColor = 'rgba(23, 161, 255, 0.6)'; // 半透明的蓝色背景
  147. // ...其他样式设置
  148.  
  149. let opacity = 0.6; // 初始透明度
  150. let increasing = true; // 透明度递增标志
  151.  
  152. const breathAnimation = setInterval(() => {
  153. if (increasing) {
  154. opacity += 0.01;
  155. } else {
  156. opacity -= 0.01;
  157. }
  158.  
  159. if (opacity >= 0.8) {
  160. increasing = false;
  161. } else if (opacity <= 0.6) {
  162. increasing = true;
  163. }
  164.  
  165. miniSidebar.style.backgroundColor = `rgba(23, 161, 255, ${opacity})`;
  166. }, 50); // 设置呼吸动画的时间间隔
  167.  
  168. miniSidebar.addEventListener('mouseenter', () => {
  169. clearInterval(breathAnimation); // 停止呼吸动画
  170. sidebarContainer.style.right = '0';
  171. clearTimeout(timer);
  172. });
  173.  
  174. miniSidebar.addEventListener('mouseleave', () => {
  175. breathAnimation(); // 重新开始呼吸动画
  176. sidebarContainer.style.right = '-140px';
  177. showMiniSidebar();
  178. });
  179.  
  180. document.body.appendChild(miniSidebar);
  181. }
  182. }
  183.  
  184. // 检查链接是否仅为域名
  185. function isDomainOnly(url) {
  186. const domain = window.location.hostname;
  187. return url === `http://${domain}/` || url === `https://${domain}/`;
  188. }
  189.  
  190. // 获取图片 ID
  191. function getImageId(url) {
  192. const match = url.match(/\/t\/\?id=(\d+)/);
  193. return match ? match[1] : null;
  194. }
  195.  
  196. // 页面加载完毕后执行
  197. window.addEventListener('load', () => {
  198. const uniqueLinks = new Set();
  199. const tagsWithImages = [];
  200. const tagsWithoutImages = [];
  201. const characters = [];
  202. const h1Links = [];
  203. const tagsElements = document.querySelectorAll('.tags a');
  204. const pElements = document.querySelectorAll('p');
  205. const biaotiElements = document.querySelectorAll('.biaoti');
  206. const h1Elements = document.querySelectorAll('h1');
  207.  
  208. pElements.forEach(pElement => {
  209. const linkElement = pElement.querySelector('a');
  210. if (linkElement && !isDomainOnly(linkElement.href) && !uniqueLinks.has(linkElement.href)) {
  211. const tagName = linkElement.textContent;
  212. const tagLink = linkElement.href;
  213. const imageId = getImageId(tagLink);
  214. if (imageId) {
  215. tagsWithImages.push({ name: tagName, link: tagLink, imageId: imageId });
  216. } else {
  217. tagsWithoutImages.push({ name: tagName, link: tagLink });
  218. }
  219. uniqueLinks.add(tagLink);
  220. }
  221. });
  222.  
  223. tagsElements.forEach(tagElement => {
  224. const tagName = tagElement.textContent;
  225. const tagLink = tagElement.href;
  226. if (!isDomainOnly(tagLink) && !uniqueLinks.has(tagLink)) {
  227. const imageId = getImageId(tagLink);
  228. if (imageId) {
  229. tagsWithImages.push({ name: tagName, link: tagLink, imageId: imageId });
  230. } else {
  231. tagsWithoutImages.push({ name: tagName, link: tagLink });
  232. }
  233. uniqueLinks.add(tagLink);
  234. }
  235. });
  236.  
  237. biaotiElements.forEach(biaotiElement => {
  238. const biaotiText = biaotiElement.textContent.trim();
  239. const biaotiWords = biaotiText.split(' ');
  240. biaotiWords.forEach(word => {
  241. const character = word.trim();
  242. if (character.length > 0 && !characters.includes(character)) {
  243. characters.push(character);
  244. }
  245. });
  246. });
  247.  
  248. h1Elements.forEach(h1Element => {
  249. const h1Text = h1Element.textContent.trim();
  250. const h1Words = h1Text.split(' ');
  251. h1Words.forEach(word => {
  252. const linkText = word.trim();
  253. if (linkText.length > 0 && !h1Links.includes(linkText)) {
  254. h1Links.push(linkText);
  255. }
  256. });
  257. });
  258.  
  259. if (tagsWithImages.length > 0 || tagsWithoutImages.length > 0 || characters.length > 0 || h1Links.length > 0) {
  260. createSidebar(tagsWithImages, tagsWithoutImages, characters, h1Links);
  261. }
  262. });
  263.  
  264. // 为侧边栏添加样式
  265. GM_addStyle(`
  266. /* 添加额外的样式 */
  267. /* 自定义滚动条样式 */
  268. ::-webkit-scrollbar {
  269. width: 8px;
  270. }
  271.  
  272. ::-webkit-scrollbar-thumb {
  273. background-color: #414141;
  274. border-radius: 8px;
  275. }
  276.  
  277. ::-webkit-scrollbar-track {
  278. background-color: #2b2b2b;
  279. border-radius: 8px;
  280. }
  281. `);
  282.  
  283. })();

QingJ © 2025

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