知乎工具箱

知乎工具箱,各种奇奇怪怪的小功能~

  1. // ==UserScript==
  2. // @name 知乎工具箱
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.3
  5. // @description 知乎工具箱,各种奇奇怪怪的小功能~
  6. // @author kuubee
  7. // @match https://*.zhihu.com/*
  8. // @icon https://www.google.com/s2/favicons?domain=mozilla.org
  9. // @grant none
  10. // @noframes
  11. // ==/UserScript==
  12.  
  13. const ZHI_HU_BLUE = "#06f";
  14. (function () {
  15. "use strict";
  16. window.onload = () => {
  17. if (window.firstFlag) return;
  18. window.firstFlag = true;
  19. ZhihuUtils.aJumpOptimization();
  20. ZhihuUtils.answerListInit();
  21. };
  22. })();
  23. class ZhihuUtils {
  24. // a 标签跳转优化
  25. static aJumpOptimization() {
  26. window.addEventListener("click", (e) => {
  27. if (e.target.tagName !== "A") return;
  28. const href = e.target.href;
  29. const matchList = href.match(
  30. /https?:\/\/link\.zhihu\.com\/\?target=(.*)/
  31. );
  32. if (!matchList) return;
  33. if (!matchList[0]) return;
  34. if (!matchList[1]) return;
  35. const targetHref = decodeURIComponent(matchList[1]);
  36. e.preventDefault();
  37. window.open(targetHref);
  38. });
  39. }
  40.  
  41. // 初始化问答列表
  42. static answerListInit() {
  43. // 旧的列表长度
  44. let oldListLenght = 0;
  45. /**
  46. * @param {HTMLElement} rootEle 根列表元素
  47. */
  48. const init = (rootEle) => {
  49. const listItemDom = Array.from(
  50. rootEle.querySelectorAll(
  51. ".Card.TopstoryItem.TopstoryItem--old.TopstoryItem-isRecommend"
  52. )
  53. );
  54. if (listItemDom.length <= 0) {
  55. oldListLenght = 0;
  56. return console.log("无数据");
  57. }
  58. if (listItemDom.length === oldListLenght) return console.log("数量未变");
  59. console.log("数量改变,重新计算", oldListLenght, listItemDom.length);
  60. // 只处理新增的数据
  61. listItemDom.slice(oldListLenght, listItemDom.length).forEach((item) => {
  62. const firstChild = item.children[0];
  63. const cardInfo = JSON.parse(firstChild.dataset?.zaExtraModule ?? "{}");
  64. if (
  65. Object.keys(cardInfo).length <= 0 ||
  66. item.className === "Pc-feedAd-container "
  67. )
  68. return ZhihuUtils.hiddenAD(item);
  69. if (cardInfo?.card?.has_video)
  70. return ZhihuUtils.hiddenVidelAnswer(firstChild);
  71. });
  72. oldListLenght = listItemDom.length;
  73. };
  74. const listRootDom = document.querySelector("#TopstoryContent");
  75. const listRootDomObs = new MutationObserver(() => init(listRootDom));
  76. listRootDomObs.observe(listRootDom, {
  77. attributes: false,
  78. childList: true,
  79. subtree: true
  80. });
  81. init(listRootDom);
  82. }
  83.  
  84. /**
  85. * @param {HTMLElement} ele 对应的元素
  86. */
  87. static hiddenAD(ele) {
  88. console.log("这个card 是一个广告");
  89. ele.style.display = "none";
  90. }
  91.  
  92. /**
  93. * @param {HTMLElement} ele 对应的元素
  94. */
  95. static hiddenVidelAnswer(ele) {
  96. console.log("这是一个视频回答");
  97. // 标题 dom
  98. const titleDom = ele.querySelector(".ContentItem-title");
  99. const titleInnterDom =
  100. titleDom.querySelector("div") ?? titleDom.querySelector("a");
  101. // 视频 dom
  102. const videoDom =
  103. ele.querySelector(".VideoAnswerPlayer") ??
  104. ele.querySelector(".ZVideoItem-video");
  105. if (videoDom) videoDom.style.display = "none";
  106. // 创建 tag dom
  107. const tagDom = document.createElement("div");
  108. // 调整样式
  109. // tag 样式
  110. /** @type {CSSStyleDeclaration} **/
  111. const tagStyleObj = {
  112. border: `2px solid ${ZHI_HU_BLUE}`,
  113. borderRadius: "10px",
  114. padding: "2px 0",
  115. fontWeight: "400",
  116. textAlign: "center",
  117. minWidth: "80px",
  118. background: "#fff",
  119. boxSizing: "border-box",
  120. color: ZHI_HU_BLUE,
  121. fontSize: "12px",
  122. marginRight: "10px",
  123. userSelect: "none"
  124. };
  125. for (const key in tagStyleObj) {
  126. if (Object.hasOwnProperty.call(tagStyleObj, key)) {
  127. const element = tagStyleObj[key];
  128. tagDom.style[key] = element;
  129. }
  130. }
  131.  
  132. // title 样式
  133. titleDom.style.display = "flex";
  134. titleDom.style.alignItems = "center";
  135. titleDom.style.marginBottom = "10px";
  136. // 插入元素
  137. tagDom.innerText = "视频回答";
  138. titleDom.insertBefore(tagDom, titleInnterDom);
  139. }
  140. }

QingJ © 2025

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