知乎增强

移除登录弹窗、一键收起回答、收起当前回答/评论(点击两侧空白处)、快捷回到顶部(右键两侧空白处)、屏蔽指定用户、屏蔽盐选内容、置顶显示时间、显示问题时间、区分问题文章、默认高清原图、默认站外直链

目前为 2021-05-07 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name 知乎增强
  3. // @version 1.3.7
  4. // @author X.I.U
  5. // @description 移除登录弹窗、一键收起回答、收起当前回答/评论(点击两侧空白处)、快捷回到顶部(右键两侧空白处)、屏蔽指定用户、屏蔽盐选内容、置顶显示时间、显示问题时间、区分问题文章、默认高清原图、默认站外直链
  6. // @match *://www.zhihu.com/*
  7. // @match *://zhuanlan.zhihu.com/*
  8. // @icon https://static.zhihu.com/heifetz/favicon.ico
  9. // @grant GM_registerMenuCommand
  10. // @grant GM_unregisterMenuCommand
  11. // @grant GM_openInTab
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @grant GM_notification
  15. // @license GPL-3.0 License
  16. // @run-at document-end
  17. // @namespace https://greasyfork.org/scripts/412205
  18. // ==/UserScript==
  19.  
  20. var menu_ALL = [
  21. ['menu_collapsedAnswer', '一键收起回答', '一键收起回答', true],
  22. ['menu_collapsedNowAnswer', '收起当前回答/评论(点击两侧空白处)', '收起当前回答/评论', true],
  23. ['menu_backToTop', '快捷回到顶部(右键两侧空白处)', '快捷回到顶部', true],
  24. ['menu_blockUsers', '屏蔽指定用户(测试)', '屏蔽指定用户', false],
  25. ['menu_blockYanXuan', '屏蔽盐选内容', '屏蔽盐选内容', false],
  26. ['menu_publishTop', '置顶显示时间', '置顶显示时间', true],
  27. ['menu_allTime', '完整显示时间', '完整显示时间', true],
  28. ['menu_typeTips', '区分问题文章', '区分问题文章', true],
  29. ['menu_directLink', '默认站外直链', '默认站外直链', true]
  30. ], menu_ID = [], blockUsersList = ['故事档案局', '盐选推荐', '盐选科普', '盐选成长计划', '知乎盐选会员', '知乎盐选创作者', '盐选心理', '盐选健康必修课', '盐选奇妙物语', '盐选生活馆', '盐选职场', '盐选文学甄选', '盐选作者小管家', '盐选博物馆', '盐选点金', '盐选测评室', '盐选科技前沿', '盐选会员精品'];
  31. for (let i=0;i<menu_ALL.length;i++){ // 如果读取到的值为 null 就写入默认值
  32. if (GM_getValue(menu_ALL[i][0]) == null){GM_setValue(menu_ALL[i][0], menu_ALL[i][3])};
  33. }
  34. registerMenuCommand();
  35.  
  36. // 注册脚本菜单
  37. function registerMenuCommand() {
  38. if (menu_ID.length > menu_ALL.length){ // 如果菜单ID数组多于菜单数组,说明不是首次添加菜单,需要卸载所有脚本菜单
  39. for (let i=0;i<menu_ID.length;i++){
  40. GM_unregisterMenuCommand(menu_ID[i]);
  41. }
  42. }
  43. for (let i=0;i<menu_ALL.length;i++){ // 循环注册脚本菜单
  44. menu_ALL[i][3] = GM_getValue(menu_ALL[i][0]);
  45. menu_ID[i] = GM_registerMenuCommand(`[ ${menu_ALL[i][3]?'√':'×'} ] ${menu_ALL[i][1]}`, function(){menu_switch(`${menu_ALL[i][3]}`,`${menu_ALL[i][0]}`,`${menu_ALL[i][2]}`)});
  46. }
  47. menu_ID[menu_ID.length] = GM_registerMenuCommand('反馈 & 建议', function () {window.GM_openInTab('https://github.com/XIU2/UserScript#xiu2userscript', {active: true,insert: true,setParent: true});window.GM_openInTab('https://greasyfork.org/zh-CN/scripts/419081/feedback', {active: true,insert: true,setParent: true});});
  48. }
  49.  
  50.  
  51. // 菜单开关
  52. function menu_switch(menu_status, Name, Tips) {
  53. if (menu_status == 'true'){
  54. GM_setValue(`${Name}`, false);
  55. GM_notification({text: `已关闭 [${Tips}] 功能\n(刷新网页后生效)`, timeout: 3500});
  56. }else{
  57. GM_setValue(`${Name}`, true);
  58. GM_notification({text: `已开启 [${Tips}] 功能\n(刷新网页后生效)`, timeout: 3500});
  59. }
  60. registerMenuCommand(); // 重新注册脚本菜单
  61. };
  62.  
  63.  
  64. // 返回菜单值
  65. function menu_value(menuName) {
  66. for (let menu of menu_ALL) {
  67. if (menu[0] == menuName) {
  68. return menu[3]
  69. }
  70. }
  71. }
  72.  
  73.  
  74. // 一键收起回答
  75. function collapsedAnswer() {
  76. if (!menu_value('menu_collapsedAnswer')) return
  77. let button_Add = `<button id="collapsed-button" data-tooltip="收起回答" data-tooltip-position="left" data-tooltip-will-hide-on-click="false" aria-label="收起回答" type="button" class="Button CornerButton Button--plain"><svg class="ContentItem-arrowIcon is-active" aria-label="收起回答" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M16.036 19.59a1 1 0 0 1-.997.995H9.032a.996.996 0 0 1-.997-.996v-7.005H5.03c-1.1 0-1.36-.633-.578-1.416L11.33 4.29a1.003 1.003 0 0 1 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.005z"></path></svg></button>`
  78. let style_Add = document.createElement('style');
  79. style_Add.innerHTML = '.CornerButton{margin-bottom:8px !important;}.CornerButtons{bottom:45px !important;}';
  80. document.head.appendChild(style_Add);
  81. document.querySelector('.CornerAnimayedFlex').insertAdjacentHTML('afterBegin', button_Add);
  82. document.getElementById('collapsed-button').onclick = function () {
  83. document.querySelectorAll('.ContentItem-rightButton').forEach(function (el) {
  84. if (el.hasAttribute('data-zop-retract-question')) {
  85. el.click()
  86. }
  87. });
  88. }
  89. }
  90.  
  91.  
  92. // 收起当前回答、评论(监听点击事件,点击网页两侧空白处)
  93. function collapsedNowAnswer(selectors) {
  94. backToTop(selectors) // 快捷回到顶部
  95. if (!menu_value('menu_collapsedNowAnswer')) return
  96. document.querySelector(selectors).onclick = function(event){
  97. if (event.target==this) {
  98. let rightButton = document.querySelector('.ContentItem-actions.Sticky.RichContent-actions.is-fixed.is-bottom')
  99. if (rightButton) { // 悬浮的 [收起回答](此时正在浏览回答内容 [头部区域 + 中间区域])
  100. // 固定的 [收起评论](先看看是否展开评论)
  101. let commentCollapseButton = rightButton.querySelector('button.Button.ContentItem-action.Button--plain.Button--withIcon.Button--withLabel:first-of-type')
  102. if (commentCollapseButton && commentCollapseButton.innerText.indexOf('收起评论') > -1) {
  103. commentCollapseButton.click();
  104. }
  105. // 再去收起回答
  106. rightButton = rightButton.querySelector('.ContentItem-rightButton')
  107. if (rightButton && rightButton.hasAttribute('data-zop-retract-question')) {
  108. rightButton.click();
  109. }
  110. } else { // 固定的 [收起回答](此时正在浏览回答内容 [尾部区域])
  111. for (let el of document.querySelectorAll('.ContentItem-rightButton')) {
  112. if (el.hasAttribute('data-zop-retract-question')) {
  113. if (isElementInViewport(el)) {
  114. // 固定的 [收起评论](先看看是否展开评论)
  115. let commentCollapseButton = el.parentNode.querySelector('button.Button.ContentItem-action.Button--plain.Button--withIcon.Button--withLabel:first-of-type')
  116. if (commentCollapseButton && commentCollapseButton.innerText.indexOf('收起评论') > -1) {
  117. commentCollapseButton.click(); // 如果展开了评论,就收起评论
  118. }
  119. el.click() // 再去收起回答
  120. break
  121. }
  122. }
  123. }
  124. }
  125.  
  126. var commentCollapseButton_ = false;
  127. // 悬浮的 [收起评论](此时正在浏览评论内容 [中间区域])
  128. let commentCollapseButton = document.querySelector('.CommentCollapseButton')
  129. if (commentCollapseButton) {
  130. commentCollapseButton.click();
  131. } else { // 固定的 [收起评论](此时正在浏览评论内容 [头部区域])
  132. let commentCollapseButton_1 = document.querySelectorAll('.ContentItem-actions > button.Button.ContentItem-action.Button--plain.Button--withIcon.Button--withLabel:first-of-type, .ContentItem-action > button.Button.Button--plain.Button--withIcon.Button--withLabel:first-of-type')
  133. if (commentCollapseButton_1.length > 0) {
  134. for (let el of commentCollapseButton_1) {
  135. if (el.innerText.indexOf('收起评论') > -1) {
  136. if (isElementInViewport(el)) {
  137. el.click()
  138. commentCollapseButton_ = true // 如果找到并点击了,就没必要执行下面的代码了(可视区域中没有 [收起评论] 时)
  139. break
  140. }
  141. }
  142. }
  143. }
  144. if (commentCollapseButton_ == false) { // 可视区域中没有 [收起评论] 时(此时正在浏览评论内容 [头部区域] + [尾部区域](不上不下的,既看不到固定的 [收起评论] 又看不到悬浮的 [收起评论])),需要判断可视区域中是否存在评论元素
  145. let commentCollapseButton_1 = document.querySelectorAll('.NestComment')
  146. if (commentCollapseButton_1.length > 0) {
  147. for (let el of commentCollapseButton_1) {
  148. if (isElementInViewport(el)) {
  149. let commentCollapseButton = el.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector('.ContentItem-actions > button.Button.ContentItem-action.Button--plain.Button--withIcon.Button--withLabel:first-of-type')
  150. if (commentCollapseButton.innerText.indexOf('收起评论') > -1) {
  151. commentCollapseButton.click()
  152. break
  153. }
  154. }
  155. }
  156. }
  157. }
  158. }
  159. }
  160. }
  161. }
  162.  
  163.  
  164. // 回到顶部(监听点击事件,鼠标右键点击网页两侧空白处)
  165. function backToTop(selectors) {
  166. if (!menu_value('menu_backToTop')) return
  167. document.querySelector(selectors).oncontextmenu = function(event){
  168. if (event.target==this) {
  169. event.preventDefault();
  170. window.scrollTo(0,0)
  171. }
  172. }
  173. }
  174.  
  175.  
  176. //获取元素是否在可视区域
  177. function isElementInViewport(el) {
  178. let rect = el.getBoundingClientRect();
  179. return (
  180. rect.top >= 0 &&
  181. rect.left >= 0 &&
  182. rect.bottom <=
  183. (window.innerHeight || document.documentElement.clientHeight) &&
  184. rect.right <=
  185. (window.innerWidth || document.documentElement.clientWidth)
  186. );
  187. }
  188.  
  189.  
  190. // 屏蔽指定用户(测试)
  191. function blockUsers(type) {
  192. if (!menu_value('menu_blockUsers')) return
  193. switch(type) {
  194. case 'index':
  195. blockUsers_index();
  196. break;
  197. case 'question':
  198. blockUsers_question();
  199. break;
  200. case 'search':
  201. blockUsers_search();
  202. break;
  203. }
  204.  
  205. function blockUsers_index() {
  206. let blockUsers = e => {
  207. if (e.target.innerHTML && e.target.getElementsByClassName('Feed').length > 0) {
  208. let item = e.target.getElementsByClassName('Feed')[0].getElementsByClassName('ContentItem AnswerItem')[0]; // 用户名所在元素
  209. if (item) {
  210. blockUsersList.forEach(function(item1){ // 遍历用户黑名单
  211. if (item.dataset.zop.indexOf('authorName":"' + item1 + '",') > -1) { // 找到就删除该信息流
  212. console.log(item.dataset.zop);
  213. item.parentNode.parentNode.remove();
  214. }
  215. })
  216. }
  217. }
  218. }
  219. document.addEventListener('DOMNodeInserted', blockUsers); // 监听插入事件
  220.  
  221. let listItem = document.getElementsByClassName('Card TopstoryItem TopstoryItem--old TopstoryItem-isRecommend');
  222. Array.from(listItem).forEach(function(item){ // 遍历所有回答
  223. let listName = item.querySelector('.ContentItem.AnswerItem') // 用户名所在元素
  224. if (listName) {
  225. blockUsersList.forEach(function(item1){ // 遍历用户黑名单
  226. if (listName.dataset.zop.indexOf('authorName":"' + item1 + '",') > -1) { // 找到就删除该信息流
  227. console.log(listName.dataset.zop);
  228. item.remove();
  229. }
  230. })
  231. }
  232. })
  233. }
  234.  
  235. function blockUsers_question() {
  236. let blockUsers = e => {
  237. if (e.target.innerHTML && e.target.getElementsByClassName('ContentItem AnswerItem').length > 0) {
  238. let item = e.target.getElementsByClassName('ContentItem AnswerItem')[0]; // 用户名所在元素
  239. if (item) {
  240. blockUsersList.forEach(function(item1){ // 遍历用户黑名单
  241. if (item.dataset.zop.indexOf('authorName":"' + item1 + '",') > -1) { // 找到就删除该回答
  242. console.log(item.dataset.zop)
  243. item.parentNode.remove();
  244. }
  245. })
  246. }
  247. }
  248. }
  249. document.addEventListener('DOMNodeInserted', blockUsers); // 监听插入事件
  250.  
  251. let listItem = document.getElementsByClassName('ContentItem AnswerItem');
  252. Array.from(listItem).forEach(function(item){ // 遍历所有回答 // 用户名所在元素
  253. if (item) {
  254. blockUsersList.forEach(function(item1){ // 遍历用户黑名单
  255. if (item.dataset.zop.indexOf('authorName":"' + item1 + '",') > -1) { // 找到就删除该回答
  256. console.log(item.dataset.zop)
  257. item.parentNode.remove();
  258. }
  259. })
  260. }
  261. })
  262. }
  263.  
  264. function blockUsers_search() {
  265. let blockUsers = e => {
  266. if (e.target.innerHTML && e.target.getElementsByClassName('List-item').length > 0) {
  267. let item = e.target.getElementsByClassName('List-item')[0];
  268. let listName = item.querySelector('.RichText.ztext.CopyrightRichText-richText b') // 用户名所在元素
  269. if (listName) {
  270. blockUsersList.forEach(function(item1){ // 遍历用户黑名单
  271. if (item1 === listName.innerText) { // 找到就删除该搜索结果
  272. console.log(listName.innerText);
  273. item.parentNode.remove();
  274. }
  275. })
  276. }
  277. }
  278. }
  279. document.addEventListener('DOMNodeInserted', blockUsers); // 监听插入事件
  280. }
  281. }
  282.  
  283.  
  284. // 屏蔽盐选内容
  285. function blockYanXuan() {
  286. if (!menu_value('menu_blockYanXuan')) return
  287. let blockYanXuan = e => {
  288. if (e.target.innerHTML && e.target.getElementsByClassName('KfeCollection-PurchaseBtn-mask').length > 0) {
  289. let item = e.target.getElementsByClassName('KfeCollection-PurchaseBtn-mask')[0];
  290. item.parentNode.parentNode.parentNode.parentNode.parentNode.remove();
  291. }
  292. }
  293. document.addEventListener('DOMNodeInserted', blockYanXuan); // 监听插入事件
  294.  
  295. let listItem = document.getElementsByClassName('List-item');
  296. Array.from(listItem).forEach(function(item){
  297. if (item.getElementsByClassName('KfeCollection-PurchaseBtn-mask').length > 0) {
  298. item.remove();
  299. }
  300. })
  301. }
  302.  
  303.  
  304. var postNum;
  305. // 区分问题文章
  306. function addTypeTips() {
  307. if (!menu_value('menu_typeTips')) return
  308. // URL 匹配正则表达式
  309. let patt_zhuanlan = /zhuanlan.zhihu.com/,
  310. patt_question = /question\/\d+/,
  311. patt_question_answer = /answer\/\d+/,
  312. patt_video = /\/zvideo\//,
  313. patt_tip = /zhihu_e_tips/
  314. let postList = document.querySelectorAll('h2.ContentItem-title a');
  315. postNum = document.querySelectorAll('small.zhihu_e_tips');
  316. //console.log(`${postList.length} ${postNum.length}`)
  317. if (postList.length > postNum.length) {
  318. for (let num = postNum.length;num<postList.length;num++) {
  319. if (!patt_tip.test(postList[num].innerHTML)) { // 判断是否已添加
  320. if (patt_zhuanlan.test(postList[num].href)) { // 如果是文章
  321. postList[num].innerHTML = `<small class="zhihu_e_tips" style="color: #ffffff;font-weight: normal;font-size: 12px;padding: 0 3px;border-radius: 2px;background-color: #2196F3;display: inline-block;height: 18px;">文章</small> ` + postList[num].innerHTML
  322. } else if (patt_question.test(postList[num].href)) { // 如果是问题
  323. if (!postList[num].getAttribute('data-tooltip')) { // 排除用户名后面的蓝标、黄标等链接
  324. if (patt_question_answer.test(postList[num].href)) { // 如果是指向回答的问题(而非指向纯问题的链接)
  325. postList[num].innerHTML = `<small class="zhihu_e_tips" style="color: #ffffff;font-weight: normal;font-size: 12px;padding: 0 3px;border-radius: 2px;background-color: #f68b83;display: inline-block;height: 18px;">问题</small> ` + postList[num].innerHTML
  326. } else {
  327. postList[num].innerHTML = `<small class="zhihu_e_tips" style="color: #ffffff;font-weight: normal;font-size: 12px;padding: 0 3px;border-radius: 2px;background-color: #ff5a4e;display: inline-block;height: 18px;">问题</small> ` + postList[num].innerHTML
  328. }
  329. }
  330. } else if (patt_video.test(postList[num].href)) { // 如果是视频
  331. postList[num].innerHTML = `<small class="zhihu_e_tips" style="color: #ffffff;font-weight: normal;font-size: 12px;padding: 0 3px;border-radius: 2px;background-color: #00BCD4;display: inline-block;height: 18px;">视频</small> ` + postList[num].innerHTML
  332. }
  333. //postNum += 1;
  334. }
  335. }
  336. }
  337. }
  338.  
  339.  
  340. // 监听 网页插入元素 事件
  341. function addEventListener_DOMNodeInserted() {
  342. // 知乎免登录,来自:https://greasyfork.org/zh-CN/scripts/417126
  343. let removeLoginModal = e => {
  344. if (e.target.innerHTML && e.target.getElementsByClassName('Modal-wrapper').length > 0) {
  345. if (e.target.getElementsByClassName('Modal-wrapper')[0].querySelector('.signFlowModal')){
  346. e.target.getElementsByClassName('Modal-wrapper')[0].remove();
  347. }
  348. setTimeout(() => {document.documentElement.style.overflowY = 'scroll';}, 0);
  349. }
  350. }
  351.  
  352. // 收起当前评论(监听点击事件,点击网页两侧空白处)
  353. let collapseNowComment = e => {
  354. if (e.target.innerHTML && e.target.getElementsByClassName('Modal-wrapper Modal-enter').length > 0) {
  355. document.getElementsByClassName('Modal-backdrop')[0].onclick = function(event){
  356. if (event.target==this) {
  357. let closeButton = document.getElementsByClassName('Modal-closeButton')[0]
  358. if(closeButton) {
  359. closeButton.click();
  360. }
  361. }
  362. }
  363. }
  364. }
  365.  
  366. if (document.querySelector('button.AppHeader-login')){ // 未登录时才会监听并移除登录弹窗
  367. document.addEventListener('DOMNodeInserted', removeLoginModal);
  368. document.querySelector('button.AppHeader-login').onclick=function(){location.href='https://www.zhihu.com/signin';} // [登录]按钮跳转至登录页面
  369. document.querySelector('.AppHeader-profile button.Button--primary').onclick=function(){location.href='https://www.zhihu.com/signin';} // [加入知乎]按钮跳转至注册页面(实际上是同一个页面)
  370. } else if(window.location.href.indexOf("zhuanlan") > -1){
  371. document.addEventListener('DOMNodeInserted', removeLoginModal);
  372. }
  373. document.addEventListener('DOMNodeInserted', collapseNowComment); // 收起当前评论(监听点击事件,点击网页两侧空白处)
  374. }
  375.  
  376.  
  377. // 监听 XMLHttpRequest 事件
  378. function EventXMLHttpRequest() {
  379. var _send = window.XMLHttpRequest.prototype.send
  380. function sendReplacement(data) {
  381. addTypeTips();
  382. return _send.apply(this, arguments);
  383. }
  384. window.XMLHttpRequest.prototype.send = sendReplacement;
  385. }
  386.  
  387.  
  388.  
  389. // [完整显示时间 + 置顶显示时间] 功能修改自:https://greasyfork.org/scripts/402808(从 JQuery 改为原生 JavaScript,且优化了代码)
  390. // 完整显示时间 + 置顶显示时间 - 首页
  391. function topTime_index() {
  392. let topTime = document.querySelectorAll('.TopstoryItem');if (!topTime) return
  393. topTime.forEach(function(_this) {
  394. let ContentItemTime = _this.querySelector('.ContentItem-time');if (!ContentItemTime) return
  395. if (!(ContentItemTime.classList.contains('full')) && ContentItemTime.querySelector('span') && ContentItemTime.querySelector('span').innerText != null) {
  396. // 完整显示时间
  397. topTime_allTime(ContentItemTime)
  398. // 发布时间置顶
  399. topTime_publishTop(ContentItemTime, _this, 'ContentItem-meta')
  400. }
  401. });
  402. }
  403.  
  404.  
  405. // 完整显示时间 + 置顶显示时间 - 回答页
  406. function topTime_question() {
  407. let topTime = document.querySelectorAll('.ContentItem.AnswerItem');if (!topTime) return
  408. topTime.forEach(function(_this) {
  409. let ContentItemTime = _this.querySelector('.ContentItem-time');if (!ContentItemTime) return
  410. if (!(ContentItemTime.classList.contains('full')) && ContentItemTime.querySelector('span') && ContentItemTime.querySelector('span').innerText != null) {
  411. // 完整显示时间
  412. topTime_allTime(ContentItemTime)
  413. // 发布时间置顶
  414. topTime_publishTop(ContentItemTime, _this, 'ContentItem-meta')
  415. }
  416.  
  417. });
  418.  
  419. // 问题创建时间
  420. if (!(document.querySelector('.QuestionPage .QuestionHeader-side p')) && window.location.href.indexOf("log") == -1) { // 没有执行过 且 非问题日志页
  421. let createtime = document.querySelector('.QuestionPage>[itemprop~=dateCreated]').getAttribute('content');
  422. let modifiedtime = document.querySelector('.QuestionPage>[itemprop~=dateModified]').getAttribute('content');
  423. createtime = getUTC8(new Date(createtime));
  424. modifiedtime = getUTC8(new Date(modifiedtime));
  425. // 添加到问题页右上角
  426. document.querySelector('.QuestionPage .QuestionHeader-side').insertAdjacentHTML('beforeEnd', '<div style=\"color:#8590a6; margin-top:15px\"><p>创建时间:&nbsp;&nbsp;' + createtime + '</p><p>最后编辑:&nbsp;&nbsp;' + modifiedtime + '</p></div>');
  427. }
  428. }
  429.  
  430.  
  431. // 完整显示时间 + 置顶显示时间 - 搜索结果页
  432. function topTime_search() {
  433. let topTime = document.querySelectorAll('.ContentItem.AnswerItem, .ContentItem.ArticleItem');if (!topTime) return
  434. topTime.forEach(function(_this) {
  435. let ContentItemTime = _this.querySelector('.ContentItem-time');if (!ContentItemTime) return
  436. if (!(ContentItemTime.classList.contains('full')) && ContentItemTime.querySelector('span') && ContentItemTime.querySelector('span').innerText != null) {
  437. // 完整显示时间
  438. topTime_allTime(ContentItemTime)
  439. // 发布时间置顶
  440. topTime_publishTop(ContentItemTime, _this, 'SearchItem-meta')
  441. }
  442.  
  443. });
  444. }
  445.  
  446.  
  447. // 完整显示时间 + 置顶显示时间 - 用户主页
  448. function topTime_people() {
  449. let topTime = document.querySelectorAll('.ContentItem.AnswerItem, .ContentItem.ArticleItem');if (!topTime) return
  450. topTime.forEach(function(_this) {
  451. let ContentItemTime = _this.querySelector('.ContentItem-time');if (!ContentItemTime) return
  452. if (!(ContentItemTime.classList.contains('full')) && ContentItemTime.querySelector('span') && ContentItemTime.querySelector('span').innerText != null) {
  453. // 完整显示时间
  454. topTime_allTime(ContentItemTime)
  455. // 发布时间置顶
  456. topTime_publishTop(ContentItemTime, _this, 'ContentItem-meta')
  457. }
  458.  
  459. });
  460. }
  461.  
  462.  
  463. // 完整显示时间 + 置顶显示时间 - 专栏/文章
  464. function topTime_zhuanlan() {
  465. let ContentItemTime = document.querySelector('.ContentItem-time');if (!ContentItemTime) return
  466. // 完整显示时间
  467. if (menu_value('menu_allTime')) {
  468. if (ContentItemTime.innerText.indexOf('编辑于') > -1 && !(ContentItemTime.classList.contains('doneeeeee'))) {
  469. let bianjiyu = ContentItemTime.innerText;
  470. ContentItemTime.click();
  471. ContentItemTime.innerText = (ContentItemTime.innerText + "," + bianjiyu)
  472. ContentItemTime.classList.add("doneeeeee");
  473. }
  474. }
  475.  
  476. //发布时间置顶
  477. if (menu_value('menu_publishTop') && !(document.querySelector('.Post-Header > .ContentItem-time')) && !(document.querySelector('.ContentItem-meta > .ContentItem-time'))) {
  478. ContentItemTime.style.cssText = 'padding:0px 0px 0px 0px; margin-top: 14px'
  479. let temp_time = ContentItemTime.cloneNode(true);
  480. // ContentItemTime.style.display = 'none';
  481. if (window.location.href.indexOf("column") > -1){
  482. document.querySelector('.ContentItem-meta').insertAdjacentElement('beforeEnd', temp_time);
  483. } else {
  484. document.querySelector('.Post-Header').insertAdjacentElement('beforeEnd', temp_time);
  485. }
  486. }
  487. }
  488.  
  489.  
  490. // 完整显示时间
  491. function topTime_allTime(ContentItemTime) {
  492. if (!menu_value('menu_allTime')) return
  493. if (ContentItemTime.innerText.indexOf("发布于") == -1 && ContentItemTime.innerText.indexOf("编辑于") > -1) { //只有 "编辑于" 时增加具体发布时间 data-tooltip
  494. let data_tooltip = ContentItemTime.querySelector('span').getAttribute('data-tooltip');
  495. let oldtext = ContentItemTime.querySelector('span').innerText;
  496. ContentItemTime.querySelector('span').innerText = data_tooltip + "," + oldtext;
  497. ContentItemTime.classList.add('full');
  498. } else if (ContentItemTime.innerText.indexOf("发布于") > -1 && ContentItemTime.innerText.indexOf("编辑于") == -1) { //只有 "发布于" 时替换为具体发布时间 data-tooltip
  499. let data_tooltip = ContentItemTime.querySelector('span').getAttribute('data-tooltip');
  500. ContentItemTime.querySelector('span').innerText = data_tooltip;
  501. ContentItemTime.classList.add('full');
  502. }
  503. }
  504.  
  505.  
  506. // 发布时间置顶
  507. function topTime_publishTop(ContentItemTime, _this, class_) {
  508. if (!menu_value('menu_publishTop')) return
  509. if (!ContentItemTime.parentNode.classList.contains(class_)) {
  510. let temp_time = ContentItemTime.cloneNode(true);
  511. //_this.querySelector('.RichContent .ContentItem-time').style.display = 'none';
  512. _this.querySelector('.' + class_).insertAdjacentElement('beforeEnd', temp_time);
  513. }
  514. }
  515.  
  516.  
  517. // UTC 标准时转 UTC+8 北京时间,来自:https://greasyfork.org/zh-CN/scripts/402808
  518. function getUTC8(datetime) {
  519. let month = (datetime.getMonth() + 1) < 10 ? "0" + (datetime.getMonth() + 1) : (datetime.getMonth() + 1);
  520. let date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
  521. let hours = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
  522. let minutes = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
  523. let seconds = datetime.getSeconds() < 10 ? "0" + datetime.getSeconds() : datetime.getSeconds();
  524. return (datetime.getFullYear() + "-" + month + "-" + date + "\xa0\xa0" + hours + ":" + minutes + ":" + seconds);
  525. }
  526.  
  527.  
  528. // 默认站外直链,修改自:https://greasyfork.org/scripts/402808(从 JQuery 改为原生 JavaScript)
  529. function directLink () {
  530. let link, equal, colon, externalHref, protocol, path, newHref;
  531. // 文字链接
  532. link = document.querySelectorAll('a[class*="external"]')
  533. if (link) {
  534. link.forEach(function (_this) {
  535. if (_this.getElementsByTagName('span').length > 0) {
  536. newHref = _this.innerText;
  537. _this.setAttribute('href', newHref);
  538. } else if (_this.href.indexOf("link.zhihu.com/?target=") > -1) {
  539. externalHref = _this.href;
  540. newHref = externalHref.substring(externalHref = _this.href.indexOf("link.zhihu.com/?target=") + "link.zhihu.com/?target=".length);
  541. _this.setAttribute('href', decodeURIComponent(newHref));
  542. } else {
  543. externalHref = _this.href;
  544. if (externalHref.lastIndexOf("https%3A")) {
  545. newHref = _this.href.substring(_this.href.lastIndexOf("https%3A"));
  546. } else if (externalHref.lastIndexOf("http%3A%2F%2F")) {
  547. newHref = _this.href.substring(_this.href.lastIndexOf("http%3A"));
  548. }
  549. _this.setAttribute('href', decodeURIComponent(newHref));
  550. }
  551. });
  552. }
  553.  
  554. // 卡片链接
  555. link = document.querySelectorAll('a[class*="LinkCard"]:not([class*="MCNLinkCard"]):not([class*="ZVideoLinkCard"])')
  556. if (link) {
  557. link.forEach(function (_this) {
  558. if (_this.getElementsByTagName('LinkCard-title').length > 0 && _this.getElementsByTagName('LinkCard-title')[0].indexOf("http") > -1) {
  559. newHref = _this.getElementsByTagName('LinkCard-title').innerText;
  560. _this.setAttribute('href', newHref);
  561. } else if (_this.href.indexOf("link.zhihu.com/?target=") > -1) {
  562. externalHref = _this.href;
  563. newHref = externalHref.substring(externalHref = _this.href.indexOf("link.zhihu.com/?target=") + "link.zhihu.com/?target=".length);
  564. _this.setAttribute('href', decodeURIComponent(newHref));
  565. } else {
  566. externalHref = _this.href;
  567. if (externalHref.lastIndexOf("https%3A")) {
  568. newHref = _this.href.substring(_this.href.lastIndexOf("https%3A"));
  569. } else if (externalHref.lastIndexOf("http%3A%2F%2F")) {
  570. newHref = _this.href.substring(_this.href.lastIndexOf("http%3A"));
  571. }
  572. _this.setAttribute('href', decodeURIComponent(newHref));
  573. }
  574. });
  575. }
  576.  
  577. // 旧版视频卡片链接
  578. link = document.querySelectorAll('a.VideoCard-link')
  579. if (link) {
  580. link.forEach(function (_this) {
  581. if (_this.href.indexOf('link.zhihu.com/?target=') > -1) {
  582. externalHref = _this.href;
  583. equal = externalHref.lastIndexOf('http');
  584. colon = externalHref.lastIndexOf('%3A');
  585. protocol = externalHref.substring(equal, colon);
  586. path = externalHref.substring(colon + 5, externalHref.length);
  587. newHref = protocol + '://' + path;
  588. _this.setAttribute('href', decodeURIComponent(newHref));
  589. }
  590. });
  591. }
  592. }
  593.  
  594.  
  595. // 默认高清原图,修改自:https://greasyfork.org/scripts/402808(从 JQuery 改为原生 JavaScript)
  596. function originalPic(){
  597. let pic = document.getElementsByTagName('img');if (!pic) return
  598. Array.from(pic).forEach(function(pic1){
  599. if (pic1.getAttribute('data-original') != undefined && pic1.className != 'comment_sticker') {
  600. if (pic1.getAttribute('src') != pic1.getAttribute('data-original')) {
  601. pic1.setAttribute('src', pic1.getAttribute('data-original'))
  602. }
  603. }
  604. });
  605. }
  606.  
  607.  
  608. // 默认折叠邀请,修改自:https://greasyfork.org/scripts/402808(从 JQuery 改为原生 JavaScript)
  609. function questionInvitation(){
  610. let timer = setInterval(function(){
  611. let QuestionInvitation = document.querySelector('.QuestionInvitation-content');if (!QuestionInvitation) return
  612. clearInterval(timer);
  613. QuestionInvitation.style.display = "none";
  614. document.querySelector('.QuestionInvitation-title').innerHTML = document.querySelector('.QuestionInvitation-title').innerText + '<span style="color: #8590a6;font-size: 14px;"> 展开/折叠</span>'
  615. // 点击事件(展开/折叠)
  616. document.querySelector('.Topbar').onclick = function(){
  617. let QuestionInvitation = document.querySelector('.QuestionInvitation-content')
  618. if (QuestionInvitation.style.display == 'none') {
  619. QuestionInvitation.style.display = ''
  620. } else {
  621. QuestionInvitation.style.display = 'none'
  622. }
  623. }
  624. });
  625. }
  626.  
  627.  
  628. (function() {
  629. addEventListener_DOMNodeInserted(); // 监听 网页插入元素 事件
  630. questionInvitation(); // 默认折叠邀请
  631. setInterval(originalPic,100); // 默认高清原图
  632. if (menu_value('menu_directLink')) setInterval(directLink, 100); // 默认站外直链
  633.  
  634. if (window.location.href.indexOf("question") > -1) { // 回答页 //
  635. if (window.location.href.indexOf("waiting") == -1) {
  636. collapsedAnswer(); // 一键收起回答
  637. collapsedNowAnswer(".QuestionPage"); // 收起当前回答 + 快捷返回顶部
  638. collapsedNowAnswer(".Question-main"); // 收起当前回答 + 快捷返回顶部
  639. blockUsers('question'); // 屏蔽指定用户
  640. blockYanXuan(); // 屏蔽盐选内容
  641. }
  642. setInterval(topTime_question, 300); // 置顶显示时间
  643. } else if (window.location.href.indexOf("search") > -1) { // 搜索结果页 //
  644. collapsedAnswer(); // 一键收起回答
  645. collapsedNowAnswer("main div"); // 收起当前回答 + 快捷返回顶部
  646. collapsedNowAnswer(".Search-container"); // 收起当前回答 + 快捷返回顶部
  647. setInterval(topTime_search, 300); // 置顶显示时间
  648. EventXMLHttpRequest(); // 区分问题文章
  649. blockUsers('search'); // 屏蔽指定用户
  650. } else if (window.location.href.indexOf("topic") > -1) { // 话题页 //
  651. if (window.location.href.indexOf("hot") > -1 || window.location.href.indexOf("top-answers") > -1) { // 仅限 [讨论] [精华]
  652. collapsedAnswer(); // 一键收起回答
  653. collapsedNowAnswer("main.App-main"); // 收起当前回答 + 快捷返回顶部
  654. collapsedNowAnswer(".ContentLayout"); // 收起当前回答 + 快捷返回顶部
  655. setInterval(topTime_people, 300); // 置顶显示时间
  656. EventXMLHttpRequest(); // 区分问题文章
  657. }
  658. } else if (window.location.href.indexOf("zhuanlan") > -1){ // 文章 //
  659. backToTop("article.Post-Main.Post-NormalMain"); // 快捷返回顶部
  660. backToTop("div.Post-Sub.Post-NormalSub"); // 快捷返回顶部
  661. setInterval(topTime_zhuanlan, 300); // 置顶显示时间
  662. } else if (window.location.href.indexOf("column") > -1) { // 专栏 //
  663. collapsedAnswer(); // 一键收起回答
  664. collapsedNowAnswer("main div"); // 收起当前回答 + 快捷返回顶部
  665. setInterval(topTime_zhuanlan, 300); // 置顶显示时间
  666. } else if (window.location.href.indexOf("people") > -1 || window.location.href.indexOf("org") > -1) { // 用户主页 //
  667. collapsedAnswer(); // 一键收起回答
  668. collapsedNowAnswer("main div"); // 收起当前回答 + 快捷返回顶部
  669. collapsedNowAnswer(".Profile-main"); // 收起当前回答 + 快捷返回顶部
  670. setInterval(topTime_people, 300); // 置顶显示时间
  671. } else { // 首页 //
  672. collapsedAnswer(); // 一键收起回答
  673. collapsedNowAnswer("main div"); // 收起当前回答 + 快捷返回顶部
  674. collapsedNowAnswer(".Topstory-container"); // 收起当前回答 + 快捷返回顶部
  675. setInterval(topTime_index, 300); // 置顶显示时间
  676. EventXMLHttpRequest(); // 区分问题文章
  677. blockUsers('index'); // 屏蔽指定用户
  678. }
  679. })();