b站首页推荐纯享版

这是一个清爽版b站首页的脚本,可以使得首页只有首页推荐,你不再需要忍受bilibili繁复的首页,没有直播、番剧、电视剧、电影一系列让人眼花缭乱的版块,就一个首页推荐,让你能轻松的浏览,不再是只有顶部一小块窗口还不能往回找,错过了就无了,太草了!【bilibili、b站、哔哩哔哩、首页、清爽、推荐、关注列表、时长筛选】

  1. // ==UserScript==
  2. // @name b站首页推荐纯享版
  3. // @namespace http://tampermonkey.net/
  4. // @version 3.1.3
  5. // @description 这是一个清爽版b站首页的脚本,可以使得首页只有首页推荐,你不再需要忍受bilibili繁复的首页,没有直播、番剧、电视剧、电影一系列让人眼花缭乱的版块,就一个首页推荐,让你能轻松的浏览,不再是只有顶部一小块窗口还不能往回找,错过了就无了,太草了!【bilibili、b站、哔哩哔哩、首页、清爽、推荐、关注列表、时长筛选】
  6. // @author Waflare
  7. // @match https://www.bilibili.com/
  8. // @match https://www.bilibili.com/?spm_id_from=*
  9. // @icon https://t0.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://bilibili.com&size=48
  10. // @grant GM_addStyle
  11. // @grant GM_xmlhttpRequest
  12. // @require https://code.jquery.com/jquery-3.6.0.js
  13. // @license GPL
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. 'use strict';
  18. // 获取首页推荐的数据
  19. function getFrontPage() {
  20. let url = 'https://api.bilibili.com/x/web-interface/index/top/rcmd?fresh_type=3';
  21. return new Promise((resolve, reject) => {
  22. GM_xmlhttpRequest({
  23. method: 'GET',
  24. url: url,
  25. onload: (r) => {
  26. if (JSON.parse(r.response).code !== 0) {
  27. resolve([]);
  28. return;
  29. }
  30. let result = JSON.parse(r.response).data.item;
  31. resolve(result);
  32. }
  33. })
  34. })
  35. }
  36.  
  37. // 获取关注列表视频投稿的数据
  38. function getFollowPage() {
  39. let url = `https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all?type=video&timezone_offset=-480&features=itemOpusStyle`
  40. followedOffset && (url += `&offset=${followedOffset}`);
  41. return new Promise((resolve, reject) => {
  42. GM_xmlhttpRequest({
  43. method: 'GET',
  44. url: url,
  45. onload: (r) => {
  46. if (JSON.parse(r.response).code !== 0) {
  47. resolve([]);
  48. return;
  49. }
  50. if (parseInt(JSON.parse(r.response).data.offset)) {
  51. followedOffset = parseInt(JSON.parse(r.response).data.offset);
  52. }
  53. let result = JSON.parse(r.response).data.items;
  54. resolve(result);
  55. }
  56. })
  57. })
  58. }
  59.  
  60. // 获取视频模板
  61. function getTemplate(item) {
  62. return `
  63. <a class='w_item' href='https://www.bilibili.com/video/${item.bvid}' target='_blank' id='${item.bvid}'>
  64. <div class='w_img_box'>
  65. <img src='${item.pic}@336w_190h_!web-video-rcmd-cover.webp' />
  66. <div class="w_img_box__pubdate">${formatDate(item.pubdate)}</div>
  67. <div class="w_img_box__duration">${formatTime(item.duration)}</div>
  68. </div>
  69. <div class='w_footer'>
  70. <div class="w_face">
  71. <img src='${item.owner.face}' />
  72. </div>
  73. <div class='w_detail'>
  74. <div class='w_title'>${item.title}</div>
  75. <div class='w_up'>${item.owner.name}</div>
  76. <div class='w_stat'>
  77. <div>${formatNum(item.stat.view)}播放</div>
  78. <div>${formatNum(item.stat.like)}点赞</div>
  79. </div>
  80. </div>
  81. </div>
  82. </a>
  83. `
  84. }
  85.  
  86. // 获取关注列表视频投稿的模板
  87. function getFollowedTemplate(item) {
  88. const modules = item.modules;
  89. const { face, name, pub_time } = modules.module_author;
  90. const { title, duration_text, cover, bvid, stat } = modules.module_dynamic.major.archive;
  91. return `
  92. <a class='w_item' href='https://www.bilibili.com/video/${bvid}' target='_blank' id='${bvid}'>
  93. <div class='w_img_box'>
  94. <img src='${cover}' />
  95. <div class="w_img_box__pubdate">${pub_time}</div>
  96. <div class="w_img_box__duration">${duration_text}</div>
  97. </div>
  98. <div class='w_footer'>
  99. <div class="w_face">
  100. <img src='${face}' />
  101. </div>
  102. <div class='w_detail'>
  103. <div class='w_title'>${title}</div>
  104. <div class='w_up'>${name}</div>
  105. <div class='w_stat'>
  106. <div>${stat.danmaku}弹幕</div>
  107. <div>${stat.play}播放</div>
  108. </div>
  109. </div>
  110. </div>
  111. </a>
  112. `
  113. }
  114.  
  115. // 控制模板,5个选项,分别是:全部、5分钟以下、5-10分钟、10-30分钟、30分钟以上
  116. // 选择不同的选项,会改变 localstorage 的值,用于控制视频时长的范围
  117. function getControlTemplate() {
  118. return `
  119. <div id="w_control">
  120. <div id="w_control_title">
  121. 视频时长
  122. </div>
  123. <div id="w_control_content">
  124. <div class="w_control_item">
  125. <input type="radio" name="w_control_item" id="w_control_item_1" value="1" />
  126. <label for="w_control_item_1" id="w_control_label_1">全部</label>
  127. </div>
  128. <div class="w_control_item">
  129. <input type="radio" name="w_control_item" id="w_control_item_2" value="2" />
  130. <label for="w_control_item_2" id="w_control_label_2">5分钟以下</label>
  131. </div>
  132. <div class="w_control_item">
  133. <input type="radio" name="w_control_item" id="w_control_item_3" value="3" />
  134. <label for="w_control_item_3" id="w_control_label_3">5-10分钟</label>
  135. </div>
  136. <div class="w_control_item">
  137. <input type="radio" name="w_control_item" id="w_control_item_4" value="4" />
  138. <label for="w_control_item_4" id="w_control_label_4">10-30分钟</label>
  139. </div>
  140. <div class="w_control_item">
  141. <input type="radio" name="w_control_item" id="w_control_item_5" value="5" />
  142. <label for="w_control_item_5" id="w_control_label_5">30分钟以上</label>
  143. </div>
  144. </div>
  145. <div id="w_control_content_mini"></div>
  146. </div>
  147. `
  148. }
  149.  
  150. // 视频类型控制模板,2个选项,分别是:首页视频、关注视频
  151. function getVideoTypeControlTemplate() {
  152. return `
  153. <div id="w_video_type_control">
  154. <div id="w_video_type_control_title">
  155. 视频类型
  156. </div>
  157. <div id="w_video_type_control_content">
  158. <div class="w_video_type_control_item">
  159. <input type="radio" name="w_video_type_control_item" id="w_video_type_control_item_1" value="1" />
  160. <label for="w_video_type_control_item_1" id="w_video_type_control_label_1">首页视频</label>
  161. </div>
  162. <div class="w_video_type_control_item">
  163. <input type="radio" name="w_video_type_control_item" id="w_video_type_control_item_2" value="2" />
  164. <label for="w_video_type_control_item_2" id="w_video_type_control_label_2">关注视频</label>
  165. </div>
  166. </div>
  167. <div id="w_video_type_control_content_mini"></div>
  168. </div>
  169. `
  170. }
  171.  
  172. function getSidebarBox() {
  173. return `
  174. <div id="sidebar_box">
  175. <div id='w_control_expand'>收起</div>
  176. <div id="sidebar_setting">点击展开设置</div>
  177. </div>
  178. `
  179. }
  180.  
  181. function getRefreshTemplate() {
  182. return `
  183. <div id="w_refresh_box">刷</div>
  184. `
  185. }
  186.  
  187. // 输入秒数,返回时分秒格式的时间
  188. function formatTime(time) {
  189. let hour = Math.floor(time / 3600);
  190. let minute = Math.floor((time - hour * 3600) / 60);
  191. let second = Math.floor(time - hour * 3600 - minute * 60);
  192. let result = '';
  193. if (hour > 0) {
  194. // 如果小时大于0,则显示小时,前面补0
  195. result += (hour < 10 ? '0' + hour : hour) + ':';
  196. }
  197. result += (minute < 10 ? '0' + minute : minute) + ':';
  198. result += (second < 10 ? '0' + second : second);
  199. return result;
  200. }
  201.  
  202. // 格式化时间,输入时间戳(秒),如果是一周内的时间,则显示几天前,否则返回yyyy-mm-dd格式的时间
  203. function formatDate(time) {
  204. let now = new Date();
  205. let date = new Date(time * 1000);
  206. let diff = now.getTime() - date.getTime();
  207. let day = Math.floor(diff / (24 * 3600 * 1000));
  208. let hour = Math.floor(diff / (3600 * 1000));
  209. if (hour == 0) {
  210. return Math.floor(diff / (60 * 1000)) + '分钟前';
  211. } else if (day == 0) {
  212. return hour + '小时前';
  213. } else if (day < 7) {
  214. return day + '天前';
  215. } else {
  216. return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
  217. }
  218. }
  219.  
  220. // 老版 b站
  221. async function formatData() {
  222. $('#internationalHeader').after(`
  223. <div id="w_body">
  224. <div id="w_content"></div>
  225. <div id="w_content__loading">
  226. <div class="spinner">
  227. <div class="rect1"></div>
  228. <div class="rect2"></div>
  229. <div class="rect3"></div>
  230. <div class="rect4"></div>
  231. <div class="rect5"></div>
  232. </div>
  233. <div id="w_content__loading_text"></div>
  234. </div>
  235. </div>
  236. `);
  237. $('#w_body').append(getSidebarBox())
  238. $('#sidebar_box').append(getVideoTypeControlTemplate());
  239. $('#sidebar_box').append(getControlTemplate());
  240. const videoType = window.localStorage.getItem('video-type');
  241. if (videoType == '2') {
  242. let data = []
  243. while (data.length < 20) {
  244. const res = await getFollowedVideoData();
  245. data.push(...res)
  246. }
  247. console.log('followed', data);
  248. for (let item of data) {
  249. $('#w_content').append(getFollowedTemplate(item));
  250. }
  251. } else {
  252. let data = await getVideoData();
  253. console.log(data);
  254. for (let item of data) {
  255. $('#w_content').append(getTemplate(item));
  256. }
  257. }
  258. $('#w_body').append('<div id="w_btn">顶</div>');
  259. $('#w_body').append(getRefreshTemplate());
  260. $('#w_refresh_box').on('click', refresh);
  261. $('#w_btn').on('click', backTop);
  262. }
  263.  
  264. // 新版 b站
  265. async function formatDataNew() {
  266. $('#i_cecream').after(`
  267. <div id="w_body">
  268. <div id="w_content"></div>
  269. <div id="w_content__loading">
  270. <div class="spinner">
  271. <div class="rect1"></div>
  272. <div class="rect2"></div>
  273. <div class="rect3"></div>
  274. <div class="rect4"></div>
  275. <div class="rect5"></div>
  276. </div>
  277. <div id="w_content__loading_text"></div>
  278. </div>
  279. </div>
  280. `);
  281. $('#w_body').append(getSidebarBox())
  282. $('#sidebar_box').append(getVideoTypeControlTemplate());
  283. $('#sidebar_box').append(getControlTemplate());
  284. const videoType = window.localStorage.getItem('video-type');
  285. if (videoType == '2') {
  286. let data = []
  287. while (data.length < 20) {
  288. const res = await getFollowedVideoData();
  289. data.push(...res)
  290. }
  291. console.log('followed', data);
  292. for (let item of data) {
  293. $('#w_content').append(getFollowedTemplate(item));
  294. }
  295. } else {
  296. let data = await getVideoData();
  297. console.log(data);
  298. for (let item of data) {
  299. $('#w_content').append(getTemplate(item));
  300. }
  301. }
  302. $('#w_body').append('<div id="w_btn">顶</div>');
  303. $('#w_body').append(getRefreshTemplate());
  304. $('#w_refresh_box').on('click', refresh);
  305. $('#w_btn').on('click', backTop);
  306. }
  307.  
  308. // 控制loading的显示和隐藏以及文案
  309. function setLoading(show, text = '') {
  310. $('#w_content__loading_text').text(text);
  311. if (show) {
  312. $('#w_content__loading').show();
  313. } else {
  314. $('#w_content__loading').hide();
  315. }
  316. }
  317.  
  318. // 获取视频列表,入参size表示一次的视频数量
  319. async function getVideoData(size = 20) {
  320. let data = []
  321. const videoTimeRange = window.localStorage.getItem('video-time-range');
  322. const type = ['', '5分钟以下的', '5-10分钟的', '10-30分钟的', '30分钟以上的']
  323. const videoTimeRangeType = type[videoTimeRange - 1]
  324. setLoading(true, '正在获取' + videoTimeRangeType + '视频列表,请稍候...');
  325. while (data.length < size) {
  326. let res = await getFrontPage();
  327. if (res.length == 0) {
  328. break;
  329. }
  330. // res.duration 为视频时长,单位为秒,如果视频时长不在范围内,则跳过
  331. if (videoTimeRange) {
  332. switch (videoTimeRange) {
  333. case '1':
  334. break;
  335. case '2':
  336. res = res.filter(item => item.duration < 300);
  337. break;
  338. case '3':
  339. res = res.filter(item => item.duration >= 300 && item.duration < 600);
  340. break;
  341. case '4':
  342. res = res.filter(item => item.duration >= 600 && item.duration < 1800);
  343. break;
  344. case '5':
  345. res = res.filter(item => item.duration >= 1800);
  346. break;
  347. }
  348. }
  349. data.push(...res);
  350. }
  351. setLoading(false);
  352. const len = data.length - data.length % 5;
  353. return data.slice(0, len);
  354. }
  355.  
  356. // 获取关注的视频列表
  357. let followedOffset = 0;
  358. async function getFollowedVideoData() {
  359. let data = [];
  360. const videoTimeRange = window.localStorage.getItem('video-time-range');
  361. const type = ['', '5分钟以下的', '5-10分钟的', '10-30分钟的', '30分钟以上的']
  362. const videoTimeRangeType = type[videoTimeRange - 1]
  363. setLoading(true, `正在获取${videoTimeRangeType}关注视频列表,请稍候...`);
  364. let res = await getFollowPage();
  365. if (res.length == 0) {
  366. setLoading(false);
  367. return
  368. }
  369. const duration = (item) => getSecond(item.modules.module_dynamic.major.archive.duration_text)
  370. switch (videoTimeRange) {
  371. case '1':
  372. break;
  373. case '2':
  374. res = res.filter(item => duration(item) < 300);
  375. break;
  376. case '3':
  377. res = res.filter(item => duration(item) >= 300 && duration(item) < 600);
  378. break;
  379. case '4':
  380. res = res.filter(item => duration(item) >= 600 && duration(item) < 1800);
  381. break;
  382. case '5':
  383. res = res.filter(item => duration(item) >= 1800);
  384. break;
  385. }
  386. data.push(...res);
  387. if (data.length == 0) {
  388. await getFollowedVideoData();
  389. }
  390. setLoading(false);
  391. return data;
  392. }
  393.  
  394. // 输入hh:mm:ss或者mm:ss格式的时间,返回秒数
  395. function getSecond(time) {
  396. let arr = time.split(':');
  397. let result = 0;
  398. if (arr.length === 2) {
  399. result += parseInt(arr[0]) * 60;
  400. result += parseInt(arr[1]);
  401. } else {
  402. result += parseInt(arr[0]) * 3600;
  403. result += parseInt(arr[1]) * 60;
  404. result += parseInt(arr[2]);
  405. }
  406. return result;
  407. }
  408.  
  409. let timer = null;
  410. function backTop() {
  411. let isSafari = /^(?=.Safari)(?!.Chrome)/.test(navigator.userAgent);
  412. if (isSafari) {
  413. cancelAnimationFrame(timer);
  414. timer = requestAnimationFrame(function fn() {
  415. var oTop = document.body.scrollTop || document.documentElement.scrollTop;
  416. if (oTop > 0) {
  417. scrollTo(0, oTop - oTop / 8);
  418. timer = requestAnimationFrame(fn);
  419. } else {
  420. cancelAnimationFrame(timer);
  421. }
  422. });
  423. } else {
  424. scrollTo({
  425. left: 0,
  426. top: 0,
  427. behavior: 'smooth'
  428. })
  429. }
  430. }
  431.  
  432. async function moreVideo() {
  433. const videoType = window.localStorage.getItem('video-type');
  434. if (videoType == '2') {
  435. let data = []
  436. while (data.length < 20) {
  437. const res = await getFollowedVideoData();
  438. data.push(...res)
  439. }
  440. for (let item of data) {
  441. $('#w_content').append(getFollowedTemplate(item));
  442. }
  443. } else {
  444. let data = await getVideoData();
  445. for (let item of data) {
  446. $('#w_content').append(getTemplate(item));
  447. }
  448. }
  449. }
  450.  
  451. function refresh() {
  452. backTop();
  453. const videoDom = document.getElementById('w_content')
  454. const childs = document.querySelectorAll('.w_item')
  455. childs.forEach(v => videoDom.removeChild(v))
  456. moreVideo();
  457. }
  458.  
  459. function handleExpand(state) {
  460. const sidebarDom = document.getElementById('sidebar_box');
  461. const sidebarTip = document.getElementById('sidebar_setting');
  462. if (state) {
  463. sidebarDom.style.transform = 'translateX(0)';
  464. sidebarTip.style.display = 'none';
  465. } else {
  466. sidebarDom.style.transform = 'translateX(-190px)';
  467. sidebarTip.style.display = 'block';
  468. }
  469. }
  470.  
  471. // 判断是否是新版
  472. function isNewOrOld() {
  473. return $('#i_cecream').length > 0;
  474. }
  475.  
  476. // 给视频时长选择框绑定事件
  477. function bindVideoTimeRangeEvent() {
  478. document.querySelectorAll('#w_control_content label').forEach(item => {
  479. item.addEventListener('click', function (e) {
  480. let value = e.target.getAttribute('for').split('_').pop();
  481. window.localStorage.setItem('video-time-range', value);
  482. refresh();
  483. })
  484. })
  485. }
  486.  
  487. // 给视频类型选择框绑定事件
  488. function bindVideoTypeEvent() {
  489. document.querySelectorAll('#w_video_type_control_content label').forEach(item => {
  490. item.addEventListener('click', function (e) {
  491. let value = e.target.getAttribute('for').split('_').pop();
  492. window.localStorage.setItem('video-type', value);
  493. refresh();
  494. })
  495. })
  496. }
  497.  
  498. // 给展开收起按钮绑定事件
  499. let isExpand;
  500. function bindExpandEvent() {
  501. const expandControl = document.getElementById('w_control_expand')
  502. expandControl.addEventListener('click', function () {
  503. isExpand = !isExpand;
  504. window.localStorage.setItem('isExpandLocal', isExpand);
  505. handleExpand(isExpand)
  506. })
  507. const tipsControl = document.getElementById('sidebar_setting')
  508. tipsControl.addEventListener('click', function () {
  509. isExpand = !isExpand;
  510. window.localStorage.setItem('isExpandLocal', isExpand);
  511. handleExpand(isExpand)
  512. })
  513. }
  514.  
  515. // 主函数
  516. function main() {
  517. if(isNewOrOld()){
  518. formatDataNew();
  519. } else {
  520. formatData();
  521. }
  522. bindVideoTypeEvent();
  523. bindVideoTimeRangeEvent();
  524. bindExpandEvent();
  525.  
  526. const isExpandLocal = window.localStorage.getItem('isExpandLocal');
  527. if (isExpandLocal === 'true' || isExpandLocal === undefined) {
  528. isExpand = true;
  529. } else {
  530. isExpand = false;
  531. }
  532. handleExpand(isExpand);
  533.  
  534. // 获取本地存储的视频类型,设置默认选中
  535. let videoType = window.localStorage.getItem('video-type');
  536. if (videoType) {
  537. $(`#w_video_type_control_label_${videoType}`).click();
  538. } else {
  539. $(`#w_video_type_control_label_1`).click();
  540. }
  541. // 获取本地存储的时间范围,设置默认选中
  542. let timeRange = window.localStorage.getItem('video-time-range');
  543. if (timeRange) {
  544. $(`#w_control_label_${timeRange}`).click();
  545. } else {
  546. $(`#w_control_label_1`).click();
  547. }
  548.  
  549. let timeout = null;
  550. window.onscroll = function () {
  551. //距离顶部的距离
  552. var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  553. //可视区的高度
  554. var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
  555. //滚动条的总高度
  556. var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
  557. //滚动条到底部的条件
  558. if (scrollTop + windowHeight >= scrollHeight - 10) {
  559. timeout && clearTimeout(timeout);
  560. timeout = setTimeout(() => {
  561. moreVideo();
  562. }, 300);
  563. }
  564.  
  565. const back_top = document.getElementById('w_btn');
  566. if (back_top === null) return;
  567. if (scrollTop > 20) {
  568. back_top.style.display = 'block';
  569. } else {
  570. back_top.style.display = 'none';
  571. }
  572. }
  573. }
  574.  
  575. function formatNum(num) {
  576. if (!num) {
  577. return '0';
  578. }
  579. if (num < 10000) {
  580. return num.toString();
  581. } else {
  582. return (num / 10000).toFixed(1).toString() + '万';
  583. }
  584. }
  585.  
  586. // 执行主函数
  587. main();
  588.  
  589. GM_addStyle(`
  590. body {
  591. background-color: #ffffff;
  592. }
  593. .international-home {
  594. min-height: 100vh;
  595. }
  596. .international-home .storey-box, .international-footer {
  597. display: none;
  598. }
  599. .international-home .first-screen {
  600. display: none;
  601. }
  602. .header-channel {
  603. display: none;
  604. }
  605. main, .bili-footer {
  606. display: none !important;
  607. }
  608. #w_body {
  609. display: flex;
  610. flex-direction: column;
  611. align-items: center;
  612. margin-bottom: 20px;
  613. padding-bottom: 40px;
  614. margin-top: 40px;
  615. }
  616. .bili-header__banner {
  617. height: 64px !important;
  618. min-height: 64px !important;
  619. }
  620. .animated-banner {
  621. display: none !important;
  622. }
  623. .bili-header .bili-header__banner {
  624. overflow: hidden;
  625. }
  626. .bili-header__channel {
  627. padding-top: 40px !important;
  628. }
  629. @media (prefers-color-scheme: light) {
  630. body, #w_body, #sidebar_box, .bili-header__channel {
  631. background-color: ${isNewOrOld() ? '#ffffff;' : '#f1f2f3;'} !important;
  632. }
  633. .bili-header__bar {
  634. background-color: rgba(40, 40, 40, 0.8);
  635. }
  636. }
  637. @media (prefers-color-scheme: dark) {
  638. body, #w_body, #sidebar_box, .bili-header__channel, .large-header {
  639. background-color: #222222 !important;
  640. }
  641. .channel-icons__item, .w_detail > .w_title, #sidebar_box {
  642. color: #fff !important;
  643. }
  644. .bili-header .bili-header__banner {
  645. background-color: transparent;
  646. }
  647. .bili-header .bili-header__banner .header-banner__inner {
  648. opacity: 0.7;
  649. }
  650. .bili-header .slide-down {
  651. background-color: #222222 !important;
  652. }
  653. .bili-header .slide-down svg, .bili-header .slide-down span, .bili-header .slide-down p {
  654. color: #fff !important;
  655. }
  656. .bili-feed4 .bili-header .slide-down {
  657. box-shadow: none !important;
  658. }
  659. }
  660. #sidebar_box {
  661. position: fixed;
  662. z-index: 999;
  663. left: 10px;
  664. bottom: 20px;
  665. padding: 14px;
  666. border-radius: 14px;
  667. box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
  668. transition: 0.3s transform ease-in-out;
  669. }
  670. #sidebar_setting {
  671. position: absolute;
  672. top: 50%;
  673. transform:translateY(-50%);
  674. right: -50px;
  675. width: 30px;
  676. padding: 10px 0;
  677. cursor: pointer;
  678. border-radius: 14px;
  679. writing-mode: vertical-lr;
  680. background-color: #f07775;
  681. color: #fff;
  682. text-align: center;
  683. line-height: 30px;
  684. }
  685. #w_control_expand {
  686. position: absolute;
  687. right: 10px;
  688. top: 0;
  689. }
  690. #w_control, #w_video_type_control {
  691. width: fit-content;
  692. padding: 16px 16px 0;
  693. border-radius: 4px;
  694. }
  695. #w_control {
  696. }
  697. #w_video_type_control {
  698. margin-bottom: 20px;
  699. }
  700. #w_control_title, #w_video_type_control_title {
  701. font-size: 16px;
  702. font-weight: 500;
  703. margin-bottom: 20px;
  704. }
  705. #w_control_content, #w_video_type_control_content {
  706. display: flex;
  707. flex-direction: column;
  708. justify-content: space-between;
  709. align-items: center;
  710. margin-bottom: 20px;
  711. flex-wrap: wrap;
  712. }
  713. #w_control_content > .w_control_item, #w_video_type_control_content > .w_video_type_control_item {
  714. display: flex;
  715. align-items: center;
  716. margin-bottom: 8px;
  717. }
  718. #w_content__loading {
  719. display: flex;
  720. flex-direction: column;
  721. justify-content: center;
  722. align-items: center;
  723. width: 100%;
  724. height: 100px;
  725. margin-top: 20px;
  726. margin-bottom: 80px;
  727. font-size: 14px;
  728. color: #999;
  729. }
  730. .w_control_item > label, .w_video_type_control_item > label {
  731. width: 100px;
  732. height: 30px;
  733. line-height: 30px;
  734. border: 1px solid #e6e6e6;
  735. border-radius: 4px;
  736. padding: 0 10px;
  737. margin-right: 10px;
  738. text-align: center;
  739. }
  740. .w_control_item > label:hover, .w_video_type_control_item > label:hover {
  741. cursor: pointer;
  742. border-color: #ff6699;
  743. }
  744. .w_control_item > input, .w_video_type_control_item > input {
  745. display: none;
  746. }
  747. .w_control_item > input:checked + label, .w_video_type_control_item > input:checked + label {
  748. border-color: #ff6699;
  749. color: #ff6699;
  750. }
  751.  
  752. @media screen and (max-width: 1870px) {
  753. #w_content {
  754. width: 1414px !important;
  755. }
  756. .w_item {
  757. width: 340px !important;
  758. }
  759. }
  760.  
  761. @media screen and (max-width: 1654px) {
  762. #w_content {
  763. width: 1198px !important;
  764. }
  765. .w_item {
  766. width: 285px !important;
  767. }
  768. }
  769.  
  770. @media screen and (max-width: 1438px) {
  771. #w_content {
  772. width: 999px !important;
  773. }
  774. .w_item {
  775. width: 235px !important;
  776. }
  777. }
  778.  
  779. #w_content {
  780. margin-top: 24px;
  781. max-width: 1610px;
  782. display: flex;
  783. justify-content: flex-start;
  784. flex-flow: wrap;
  785. }
  786. .w_item {
  787. width: 310px;
  788. margin-bottom: 10px;
  789. display: flex;
  790. flex-direction: column;
  791. margin-left: 10px;
  792. transition:all 0.2s;
  793. }
  794. .w_item:hover {
  795. cursor: pointer;
  796. transform: scale(1.01);
  797. }
  798. .w_item > .w_img_box{
  799. position: relative;
  800. overflow: hidden;
  801. padding-top: 62.5%;
  802. border-radius: 6px;
  803. background-image: url('https://i.w3tt.com/2021/12/05/BAH9l.png') no-repeat;
  804. }
  805. .w_img_box > img {
  806. position: absolute;
  807. top: 0;
  808. left: 0;
  809. width: 100%;
  810. }
  811. .w_img_box > .w_img_box__duration {
  812. position: absolute;
  813. bottom: 10px;
  814. right: 10px;
  815. color: #fff;
  816. font-size: 14px;
  817. font-weight: 500;
  818. background-color: rgba(0, 0, 0, 0.5);
  819. padding: 2px 4px;
  820. }
  821. .w_img_box > .w_img_box__pubdate {
  822. position: absolute;
  823. bottom: 10px;
  824. left: 10px;
  825. color: #fff;
  826. font-size: 14px;
  827. font-weight: 500;
  828. background-color: rgba(0, 0, 0, 0.5);
  829. padding: 2px 4px;
  830. }
  831. .w_item > .w_detail {
  832. width: 100%;
  833. }
  834. .w_footer {
  835. display: flex;
  836. }
  837. .w_footer > .w_face {
  838. width: 56px;
  839. padding: 10px;
  840. box-size: border-sizing;
  841. }
  842. .w_footer > .w_detail {
  843. flex: 1;
  844. }
  845. .w_face > img {
  846. width: 36px;
  847. height: 36px;
  848. border-radius: 50%;
  849. }
  850. .w_detail > .w_title {
  851. width: 100%;
  852. overflow: hidden;
  853. text-overflow: ellipsis;
  854. display: -webkit-box;
  855. -webkit-line-clamp: 2;
  856. -webkit-box-orient: vertical;
  857. font-size: 16px;
  858. line-height: 22px;
  859. border-top: 10px solid transparent;
  860. border-bottom: 5px solid transparent;
  861. }
  862. .w_detail > .w_up {
  863. font-size: 14px;
  864. color: #606060;
  865. }
  866. .w_detail > .w_stat {
  867. font-size: 12px;
  868. color: #606060;
  869. line-height: 18px;
  870. display: flex;
  871. justify-content: space-between;
  872. }
  873. #w_btn, #w_refresh_box {
  874. width: 50px;
  875. height: 50px;
  876. border-radius: 50%;
  877. line-height: 50px;
  878. font-size: 20px;
  879. text-align: center;
  880. color: #9999b2;
  881. font-weight: 600;
  882. background-color: #f6f9fa;
  883. position: fixed;
  884. right: 30px;
  885. }
  886. #w_refresh_box {
  887. bottom: 100px;
  888. }
  889. #w_btn {
  890. display: none;
  891. bottom: 30px;
  892. }
  893. #w_btn:hover, #w_refresh_box {
  894. cursor: pointer;
  895. }
  896. .palette-button-outer div[class="primary-btn"] {
  897. display: none;
  898. }
  899. .spinner {
  900. margin: 100px auto 30px;
  901. width: 50px;
  902. height: 60px;
  903. text-align: center;
  904. font-size: 10px;
  905. }
  906. .spinner > div {
  907. background-color: #67CF22;
  908. height: 100%;
  909. width: 6px;
  910. display: inline-block;
  911. -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
  912. animation: stretchdelay 1.2s infinite ease-in-out;
  913. }
  914. .spinner .rect2 {
  915. -webkit-animation-delay: -1.1s;
  916. animation-delay: -1.1s;
  917. }
  918. .spinner .rect3 {
  919. -webkit-animation-delay: -1.0s;
  920. animation-delay: -1.0s;
  921. }
  922. .spinner .rect4 {
  923. -webkit-animation-delay: -0.9s;
  924. animation-delay: -0.9s;
  925. }
  926. .spinner .rect5 {
  927. -webkit-animation-delay: -0.8s;
  928. animation-delay: -0.8s;
  929. }
  930. @-webkit-keyframes stretchdelay {
  931. 0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
  932. 20% { -webkit-transform: scaleY(1.0) }
  933. }
  934. @keyframes stretchdelay {
  935. 0%, 40%, 100% {
  936. transform: scaleY(0.4);
  937. -webkit-transform: scaleY(0.4);
  938. } 20% {
  939. transform: scaleY(1.0);
  940. -webkit-transform: scaleY(1.0);
  941. }
  942. }
  943. #w_control_expand, #w_video_type_control_expand {
  944. margin-top: 10px;
  945. writing-mode: horizontal-tb;
  946. cursor: pointer;
  947. text-align: center;
  948. }
  949. #w_control_content_mini, #w_video_type_control_content_mini {
  950. color: #9999b2;
  951. writing-mode: tb-rl;
  952. }
  953. `)
  954. })();

QingJ © 2025

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