CSDN|简书优化

支持手机端和PC端

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

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