CSDN|简书优化

支持手机端和PC端

当前为 2023-02-22 提交的版本,查看 最新版本

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