CSDN|简书优化

支持手机端和PC端

当前为 2023-01-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name CSDN|简书优化
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4.9
  5. // @description 支持手机端和PC端
  6. // @author MT-戒酒的李白染
  7. // @include http*://www.csdn.net/*
  8. // @include http*://bbs.csdn.net/*
  9. // @include http*://www.jianshu.com/*
  10. // @include http*://*blog.csdn.net/*
  11. // @include http*://download.csdn.net/*
  12. // @include http*://huaweicloud.csdn.net/*
  13. // @grant GM_addStyle
  14. // @grant GM_registerMenuCommand
  15. // @grant GM_unregisterMenuCommand
  16. // @grant GM_getValue
  17. // @grant GM_setValue
  18. // @grant GM_deleteValue
  19. // @grant GM_listValues
  20. // @grant unsafeWindow
  21. // @run-at document-start
  22. // @require https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.4.1/jquery.min.js
  23. // @require https://greasyfork.org/scripts/455186-whitesevsutils/code/WhiteSevsUtils.js?version=1135447
  24. // @require https://greasyfork.org/scripts/449471-viewer/code/Viewer.js?version=1081056
  25. // ==/UserScript==
  26.  
  27. (function () {
  28. "use strict";
  29. var GM_Menu = {
  30. data: {
  31. removeCSDNDownloadPC: {
  32. text: "电脑-移除文章底部的CSDN下载",
  33. enable: false,
  34. },
  35. articleCenter: {
  36. text: "电脑-全文居中",
  37. enable: true,
  38. },
  39. showDirect: {
  40. text: "手机-标识处理过的底部推荐文章",
  41. enable: true,
  42. },
  43. openNewTab: {
  44. text: "手机-底部推荐文章新标签页打开",
  45. enable: true,
  46. },
  47. removeCSDNDownloadMobile: {
  48. text: "手机-移除文章底部的CSDN下载",
  49. enable: false,
  50. },
  51. },
  52. init: function () {
  53. /* 初始化数据 */
  54. let _this_ = this;
  55. Object.keys(this.data).forEach((key) => {
  56. let value = GM_getValue(key);
  57. if (value == null) {
  58. GM_setValue(key, _this_.data[key].enable);
  59. value = GM_getValue(key);
  60. }
  61. _this_.data[key]["enable"] = value;
  62. });
  63. },
  64. register: function () {
  65. /* 注册油猴菜单 */
  66. let _this_ = this;
  67. Object.keys(this.data).forEach((key) => {
  68. let text = _this_.data[key]["text"];
  69. let enable = _this_.data[key]["enable"];
  70. let showText = "[" + (enable ? "√" : "×") + "]" + text;
  71. GM_registerMenuCommand(showText, function () {
  72. GM_setValue(key, enable ? false : true);
  73. window.location.reload();
  74. });
  75. });
  76. },
  77. };
  78. function waitForElementToRemove(_query_ = "") {
  79. /* 移除元素(未出现也可以等待出现) */
  80. Utils.waitForDOM(_query_).then((dom) => {
  81. dom.forEach((item) => {
  82. $(item).remove();
  83. });
  84. });
  85. }
  86. function JianShu() {
  87. /* 简书 */
  88. function isJianShu() {
  89. /* 判断是否是 简书 */
  90. return Boolean(/jianshu.com/i.test(window.location.origin));
  91. }
  92. function PC() {
  93. console.log("简书");
  94. const css = `
  95. .download-app-guidance,
  96. .call-app-btn,
  97. .collapse-tips,
  98. .note-graceful-button,
  99. .app-open,
  100. .header-wrap,
  101. .recommend-wrap.recommend-ad,
  102. .call-app-Ad-bottom,
  103. #recommended-notes p.top-title span.more,
  104. #homepage .modal,
  105. button.index_call-app-btn,
  106. span.note__flow__download,
  107. .download-guide,
  108. #footer,
  109. .comment-open-app-btn-wrap,
  110. .nav.navbar-nav + div{
  111. display:none !important;
  112. }
  113. body.reader-day-mode.normal-size {
  114. overflow: auto !important;
  115. }
  116. .collapse-free-content{
  117. height:auto !important;
  118. }
  119. .copyright{
  120. color:#000 !important;
  121. }
  122. #note-show .content .show-content-free .collapse-free-content:after{
  123. background-image:none !important;
  124. }
  125. `;
  126. GM_addStyle(css);
  127. Utils.waitForDOM('div#homepage div[class*="dialog-"]').then((dom) => {
  128. if (dom.length) {
  129. dom[0].style["visibility"] = "hidden";
  130. }
  131. });
  132. Utils.mutationObserver('div#homepage div[class*="dialog-"]', {
  133. fn: (mutations) => {
  134. if (mutations.length == 0) {
  135. return;
  136. }
  137. if (mutations[0].target.style["display"] != "none") {
  138. document
  139. .querySelector('div#homepage div[class*="dialog-"] .cancel')
  140. ?.click();
  141. }
  142. },
  143. config: {
  144. /* 子节点的变动(新增、删除或者更改) */
  145. childList: false,
  146. /* 属性的变动 */
  147. attributes: true,
  148. /* 节点内容或节点文本的变动 */
  149. characterData: true,
  150. /* 是否将观察器应用于该节点的所有后代节点 */
  151. subtree: true,
  152. },
  153. });
  154. }
  155. if (isJianShu()) {
  156. PC();
  157. }
  158. }
  159. function CSDN() {
  160. /* csdn-移动端 */
  161. function isCSDN() {
  162. /* 判断是否是 CSDN */
  163. return Boolean(/csdn.net/i.test(window.location.origin));
  164. }
  165. function Mobile() {
  166. /* 移动端 */
  167. console.log("CSDN-移动端");
  168. const css = `
  169. #mainBox{
  170. width: auto;
  171. }
  172. .user-desc.user-desc-fix{
  173. height: auto !important;
  174. overflow: auto !important;
  175. }
  176. #operate,.feed-Sign-span,
  177. .view_comment_box,
  178. .weixin-shadowbox.wap-shadowbox,
  179. .feed-Sign-span,
  180. .user-desc.user-desc-fix,
  181. .comment_read_more_box,
  182. #content_views pre.set-code-hide .hide-preCode-box,
  183. .passport-login-container,
  184. .hljs-button[data-title='登录后复制'],
  185. .article-show-more,
  186. #treeSkill,
  187. div.btn_open_app_prompt_div,
  188. div.readall_box,
  189. div.aside-header-fixed{
  190. display:none !important;
  191. }
  192. .GM-csdn-dl{
  193. padding: .24rem .32rem;
  194. width: 100%;
  195. justify-content: space-between;
  196. -webkit-box-pack: justify;
  197. border-bottom: 1px solid #F5F6F7!important;
  198. }
  199. .GM-csdn-title{
  200. font-size: .3rem;
  201. color: #222226;
  202. letter-spacing: 0;
  203. line-height: .44rem;
  204. font-weight: 600;
  205. //max-height: .88rem;
  206. word-break: break-all;
  207. overflow: hidden;
  208. display: -webkit-box;
  209. -webkit-box-orient: vertical;
  210. -webkit-line-clamp: 2
  211. }
  212. .GM-csdn-title a{
  213. word-break: break-all;
  214. color: #222226;
  215. font-weight: 600;
  216. }
  217. .GM-csdn-title em,.GM-csdn-content em{
  218. font-style: normal;
  219. color: #fc5531
  220. }
  221. .GM-csdn-content{
  222. //max-width: 5.58rem;
  223. overflow: hidden;
  224. text-overflow: ellipsis;
  225. display: -webkit-box;
  226. -webkit-line-clamp: 1;
  227. -webkit-box-orient: vertical;
  228. color: #555666;
  229. font-size: .24rem;
  230. line-height: .34rem;
  231. max-height: .34rem;
  232. word-break: break-all;
  233. -webkit-box-flex: 1;
  234. -ms-flex: 1;
  235. flex: 1;
  236. margin-top: .16rem;
  237. }
  238. .GM-csdn-img img{
  239. width: 2.18rem;
  240. height: 1.58rem;
  241. //margin-left: .16rem
  242. }
  243. .GM-csdn-Redirect{
  244. color: #fff;
  245. background-color: #f90707;
  246. font-family: sans-serif;
  247. margin: auto 2px;
  248. border: 1px solid #ccc;
  249. border-radius: 4px;
  250. padding: 0px 3px;
  251. font-size: xx-small;
  252. display: inline;
  253. white-space: nowrap;
  254. }
  255. .component-box .praise {
  256. background: #ff5722;
  257. border-radius: 5px;
  258. padding: 0px 8px;
  259. height: auto;
  260. }
  261. .component-box .praise,.component-box .share {
  262. color: #fff;
  263. }
  264. .component-box a {
  265. display: inline-block;
  266. font-size:xx-small;
  267. }
  268. .component-box {
  269. display: inline;
  270. margin: 0;
  271. position: relative;
  272. white-space:nowrap;
  273. }
  274. .csdn-edu-title{
  275. background: #4d6de1;
  276. border-radius: 5px;
  277. padding: 0px 8px;
  278. height: auto;
  279. color: #fff !important;
  280. }
  281. #comment{
  282. max-height: none !important;
  283. }
  284. #content_views pre,
  285. #content_views pre code{
  286. webkit-touch-callout: text !important;
  287. -webkit-user-select: text !important;
  288. -khtml-user-select: text !important;
  289. -moz-user-select: text !important;
  290. -ms-user-select: text !important;
  291. user-select: text !important;
  292. }
  293. #content_views pre.set-code-hide,
  294. .article_content{
  295. height: 100% !important;
  296. overflow: auto !important;
  297. }
  298. `;
  299. GM_addStyle(css);
  300. function refactoringRecommendation() {
  301. /* 重构底部推荐 */
  302. function refactoring() {
  303. /* 反复执行的重构函数 */
  304. $(".container-fluid").each((index, item) => {
  305. item = $(item);
  306. var url = ""; /* 链接 */
  307. var title = ""; /* 标题 */
  308. var content = ""; /* 内容 */
  309. var img = ""; /* 图片 */
  310. var isCSDNDownload = false; /* 判断是否是CSDN资源下载 */
  311. var isCSDNEduDownload = false; /* 判断是否是CSDN-学院资源下载 */
  312. if (item.attr("data-url")) {
  313. /* 存在真正的URL */
  314. url = item.attr("data-url");
  315. title = item.find(".recommend_title div.left").html();
  316. content = item.find(".text").html();
  317. if (item.find(".recommend-img").length) {
  318. /* 如果有图片就加进去 */
  319. item.find(".recommend-img").each((_index_, _item_) => {
  320. img += $(_item_).html();
  321. });
  322. }
  323. } else {
  324. console.log("节点上无data-url");
  325. url = item.find("a[data-type]").attr("href");
  326. title = item.find(".recommend_title div.left").html();
  327. content = item.find(".text").html();
  328. }
  329. if (GM_Menu.data.showDirect.enable) {
  330. /* 开启就添加 */
  331. title += `<div class="GM-csdn-Redirect">Redirect</div>`;
  332. }
  333. var _URL_ = new URL(url);
  334. if (
  335. _URL_.host === "download.csdn.net" ||
  336. (_URL_.host === "www.iteye.com" &&
  337. _URL_.pathname.match(/^\/resource/gi))
  338. ) {
  339. /* 该链接为csdn资源下载 */
  340. console.log("该链接为csdn资源下载");
  341. isCSDNDownload = true;
  342. title += `<div class="component-box"><a class="praise" href="javascript:;">CSDN下载</a></div>`;
  343. } else if (_URL_.origin.match(/edu.csdn.net/gi)) {
  344. /* 该链接为csdn学院下载 */
  345. isCSDNEduDownload = true;
  346. console.log("该链接为csdn学院下载");
  347. title += `<div class="component-box"><a class="csdn-edu-title" href="javascript:;">CSDN学院</a></div>`;
  348. }
  349. item.attr("class", "GM-csdn-dl");
  350. item.attr("data-url", url);
  351. item.html(
  352. `<div class="GM-csdn-title"><div class="left">${title}</div></div><div class="GM-csdn-content">${content}</div><div class="GM-csdn-img">${img}</div>`
  353. );
  354. if (
  355. (isCSDNDownload || isCSDNEduDownload) &&
  356. GM_Menu.data.removeCSDNDownloadMobile.enable
  357. ) {
  358. item.remove();
  359. }
  360. /* $("#recommend")
  361. .find(".recommend_list")
  362. .before($("#first_recommend_list").find("dl").parent().html()); */
  363. });
  364. }
  365.  
  366. Utils.mutationObserver("#recommend", {
  367. fn: () => {
  368. setTimeout(() => {
  369. refactoring();
  370. }, 300);
  371. },
  372. config: { childList: true, subtree: true, attributes: true },
  373. });
  374.  
  375. gmRecommendClickEvent();
  376. }
  377.  
  378. function gmRecommendClickEvent() {
  379. /* 底部推荐点击跳转事件 */
  380. $("body").on("click", ".GM-csdn-dl", function () {
  381. let url = $(this).attr("data-url");
  382. if (GM_Menu.data.openNewTab.enable) {
  383. window.open(url, "_blank");
  384. } else {
  385. window.location.href = url;
  386. }
  387. });
  388. }
  389.  
  390. function removeAds() {
  391. /* 去除广告 */
  392. waitForElementToRemove(".passport-login-container");
  393. waitForElementToRemove(".btn_open_app_prompt_box.detail-open-removed");
  394. waitForElementToRemove(".add-firstAd");
  395. }
  396.  
  397. $(document).ready(function () {
  398. removeAds();
  399. refactoringRecommendation();
  400. });
  401. }
  402. function PC() {
  403. /* 桌面端 */
  404. console.log("CSDN-桌面端访问");
  405. const css = `
  406. .ecommend-item-box.recommend-recommend-box,
  407. .login-mark,
  408. .opt-box.text-center,
  409. .leftPop,
  410. #csdn-shop-window,
  411. .toolbar-advert,
  412. .hide-article-box,
  413. .user-desc.user-desc-fix,
  414. .recommend-card-box,
  415. .more-article,
  416. .article-show-more{
  417. display: none !important;
  418. }
  419. .comment-list-box{
  420. max-height: none !important;
  421. }
  422. .blog_container_aside,
  423. #nav{
  424. margin-left: -45px;
  425. }
  426. .recommend-right.align-items-stretch.clearfix,.dl_right_fixed{
  427. margin-left: 45px;
  428. }
  429. #content_views pre code{
  430. user-select: text !important;
  431. }
  432. #article_content,
  433. .user-article.user-article-hide{
  434. height: auto !important;
  435. overflow: auto !important;
  436. }
  437. `;
  438. function removeClipboardHijacking() {
  439. /* 去除剪贴板劫持 */
  440. unsafeWindow.articleType = 0;
  441. unsafeWindow.csdn.copyright.textData = undefined;
  442. unsafeWindow.csdn.copyright.htmlData = undefined;
  443. $(".article-copyright")?.remove();
  444. }
  445. function unBlockCopy() {
  446. /* 取消禁止复制 */
  447. Utils.waitForDOM(".hljs-button.signin").then((dom) => {
  448. if (dom.length) {
  449. $(".hljs-button.signin").attr("data-title", "复制");
  450. $(".hljs-button.signin").on("click", function () {
  451. const copyBtn = $(this);
  452. const copyArea = $(this).parent();
  453. copyBtn.attr("data-title", "复制成功");
  454. const btnParentElement = Utils.findParentDOM(this, (dom) => {
  455. return dom.className == "prettyprint" ? true : false;
  456. });
  457. if (btnParentElement) {
  458. $(btnParentElement).bind({
  459. mouseenter: function (e) {
  460. copyBtn.attr("data-title", "复制");
  461. $(btnParentElement)
  462. .unbind("mouseenter")
  463. .unbind("mouseleave");
  464. },
  465. mouseleave: function (e) {
  466. copyBtn.attr("data-title", "复制");
  467. $(btnParentElement)
  468. .unbind("mouseenter")
  469. .unbind("mouseleave");
  470. },
  471. });
  472. }
  473. Utils.setClip(copyArea.text());
  474. });
  475. }
  476. });
  477. }
  478. function clickPreCodeAutomatically() {
  479. /* 点击代码块自动展开 */
  480. $("pre[data-index]").on("click", function () {
  481. let obj = $(this);
  482. obj.css("height", "auto");
  483. obj.find(".hide-preCode-box")?.remove();
  484. });
  485. }
  486. function restoreComments() {
  487. /* 恢复评论到正确位置 */
  488. /* 第一条评论 */
  489. Utils.waitForDOM(".first-recommend-box").then((dom) => {
  490. $(".recommend-box.insert-baidu-box.recommend-box-style").prepend(
  491. $(dom)
  492. );
  493. });
  494. /* 第二条评论 */
  495. Utils.waitForDOM(".second-recommend-box").then((dom) => {
  496. $(".recommend-box.insert-baidu-box.recommend-box-style").prepend(
  497. $(dom)
  498. );
  499. });
  500. }
  501. function identityCSDNDownload() {
  502. /* 标识CSDN下载的链接 */
  503. $(".recommend-item-box[data-url*='https://download.csdn.net/']").each(
  504. (index, item) => {
  505. if (GM_Menu.data.removeCSDNDownloadPC.enable) {
  506. item.remove();
  507. } else {
  508. $(item).find(".content-box").css("border", "2px solid red");
  509. }
  510. }
  511. );
  512. }
  513.  
  514. function articleCenter() {
  515. /* 全文居中 */
  516. if (!GM_Menu.data.articleCenter.enable) {
  517. return;
  518. }
  519. GM_addStyle(
  520. `aside.blog_container_aside{
  521. display:none !important;
  522. }
  523. #mainBox main{
  524. width: inherit !important;
  525. }
  526. `
  527. );
  528. }
  529. function addGotoRecommandButton() {
  530. /* 添加前往评论的按钮,在返回顶部的下面 */
  531. const btnElement = $(`
  532. <a class="option-box" data-type="gorecommand">
  533. <span class="show-txt" style="display:flex;opacity:100;">前往<br>评论</span>
  534. </a>
  535. `);
  536.  
  537. Utils.waitForDOM(".csdn-side-toolbar").then((dom) => {
  538. $(dom).append(btnElement);
  539. $('.option-box[data-type="gorecommand"]').on("click", function () {
  540. console.log("滚动到评论");
  541. $("html, body").animate(
  542. {
  543. scrollTop:
  544. $("#toolBarBox").offset().top -
  545. $("#csdn-toolbar").height() -
  546. 8,
  547. },
  548. 1000
  549. );
  550. });
  551. });
  552. }
  553. GM_addStyle(css);
  554. articleCenter();
  555. $(document).ready(function () {
  556. removeClipboardHijacking();
  557. unBlockCopy();
  558. identityCSDNDownload();
  559. clickPreCodeAutomatically();
  560. restoreComments();
  561. addGotoRecommandButton();
  562. });
  563. }
  564.  
  565. if (isCSDN()) {
  566. if (Utils.isPhone()) {
  567. Mobile(); /* 移动端 */
  568. } else {
  569. PC(); /* 桌面端 */
  570. }
  571. }
  572. }
  573.  
  574. GM_Menu.init();
  575. GM_Menu.register();
  576.  
  577. JianShu();
  578. CSDN();
  579. })();