Feedly 优化

一些优化

  1. // ==UserScript==
  2. // @name Feedly 优化
  3. // @homepage https://greasyfork.org/zh-CN/scripts/488038
  4. // @namespace https://feedly.com
  5. // @version 2025.06.04
  6. // @description 一些优化
  7. // @author Ejin
  8. // @match https://feedly.com/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. // 2025.03.29 简化左侧菜单,优化历史代码。
  13. // 2025.03.06 屏蔽某些关键词的内容。
  14. // 2025.02.25 消灭新特性提醒窗口(What's new,并且为漂浮状态)
  15. // 2024.08.10 优化左侧UI,将上方无用导航链接移至下方
  16. // 2024.07.14 弱化存档分类的加粗,隐藏未读数。
  17. // 2024.02.23 First-read,跳转到第一个已读项
  18. (function () {
  19. 'use strict';
  20.  
  21. setInterval(() => {//1.route 持续重复运行
  22.  
  23. // 1.1 First-read
  24. if (location.href.indexOf("feedly.com/i/subscription/feed") != -1) {
  25. if (document.querySelector(".count-followers") != null
  26. && document.querySelector(".count-followers").parentElement.parentElement.innerHTML.indexOf("First-read") == -1) {
  27. //开始匿名函数,一次性增加First-read链接并设置事件。
  28. (() => {
  29. document.querySelector(".count-followers").parentElement.parentElement.innerHTML
  30. += "<span class='detail'> <a href='javascript:;' id='First-read' style='color:#9e9e9e;'>First-read</a></span>";
  31. document.getElementById("First-read").parentElement.setAttribute(
  32. "class",document.querySelector('#First-read').parentElement.parentElement.children[0].className);// 修正class统一格式
  33. //增加First-read链接后,为它赋予事件。
  34. document.getElementById("First-read").addEventListener('click', () => {
  35. //事件开始,隐藏First-read链接,设置工作标志。
  36. document.getElementById("First-read").style.display = "none";
  37. document.querySelector("article").setAttribute("auto_roll_page","1");//正在自动滚动标志,切换其他RSS会自动消失
  38. //隐藏链接后,开始自动滚动页面,开启计时器函数
  39. ((/*setInterval*/ setInterval_index)=>{setInterval_index=setInterval(()=>{
  40. if(document.querySelector("article[auto_roll_page]") == null){
  41. //标志消失则停止滚动操作并退出
  42. clearInterval(setInterval_index);
  43. return;
  44. }
  45. //操作页面
  46. if (document.querySelectorAll(".EntryTitleLink").length > 0 || document.querySelectorAll(".entry--read").length > 0) {
  47. if (!document.querySelector(".entry--read")) {
  48. //未发现已读的内容,继续滚动页面
  49. document.querySelectorAll(".EntryTitleLink")[document.querySelectorAll(".EntryTitleLink").length - 1].scrollIntoView();
  50. } else {
  51. //发现已读内容,停止滚动。并将未读内容放在合适位置
  52. document.querySelector('#feedlyFrame').scrollBy(0, -1000);//向上滚动
  53. document.querySelector(".entry--read").scrollIntoView();//滚动到第一个已读内容
  54. document.querySelector('#feedlyFrame').scrollBy(0,
  55. 200 - document.querySelector('#feedlyFrame').clientHeight
  56. );//再往回滚动一点,即能看到一部分未读内容
  57. document.querySelector("article[auto_roll_page]").removeAttribute("auto_roll_page");//清理
  58. clearInterval(setInterval_index);//清理
  59. }
  60. }//结束页面操作
  61. },1000);})();//滚动计时器函数结束
  62. });//事件定义结束
  63. })();//整体匿名函数结束
  64. }//判断是否需要增加First-read链接,并确认页面是否准备好
  65. } //end First-read
  66.  
  67. // 1.2 待增加
  68.  
  69. }, 500);//end 1.route
  70.  
  71. // 2 重复运行
  72. // 2.1.点击、标记已读自动跳到returnALL后返回ALL页面
  73. setInterval(() => {
  74. if (document.querySelector("#header-title") && document.querySelector("#header-title").innerText == "returnALL") {
  75. //文件夹和RSS有区别,如果进的是RSS会有一个链接,所以用innerText获取是通用的
  76. document.querySelectorAll("span").forEach(ele => {
  77. if (ele.innerHTML == "All") {
  78. ele.click();
  79. }
  80. });
  81. }
  82. }, 1500);// end 跳到returnALL后返回ALL页面
  83.  
  84. // 2.2 清理列表、全文中标题的绿色广告
  85. setInterval(() => {
  86. document.querySelectorAll('.InterestingMetadataWrapper--separator-right:not([blocked="1"]) , .EntryMetadataSeparator:not([blocked="1"])').forEach(ele=>{
  87. ele.setAttribute("style","height: 1px;width:1px; overflow: hidden;display:block;");
  88. ele.setAttribute("blocked","1"); //检查过要打标签避免重复检查
  89. //console.log(ele);
  90. })
  91. }, 1500);//end 清理列表、全文中标题的绿色广告
  92. //清理右侧顶栏的升级按钮。
  93. ((setInterval_index,timecount=1)=>{setInterval_index=setInterval(()=>{
  94. if(document.querySelector("#topHeaderBarFX button")){
  95. if(document.querySelector("#topHeaderBarFX button").innerHTML.indexOf("Upgrade") != -1){
  96. document.querySelector("#topHeaderBarFX button").parentElement.setAttribute("style","height: 1px;width:1px; overflow: hidden;display:block;");
  97. clearInterval(setInterval_index);
  98. }
  99. }
  100.  
  101. if(timecount==30){clearInterval(setInterval_index);}timecount++;
  102. },2000);})(); //end 内容标题广告和顶部升级按钮
  103.  
  104. // 2.3 屏蔽某些关键词的内容(多个关键词用+号连接)。
  105. var ADKeywords=['[推广]','[VXNA]', '万 0.85 免 5', '万 0.85 免五', '万 0.5 免五', '靓号', 'XXL-', 'Pagespy', '龟男', '龟龟', '🐢'].map(item=>item.toLowerCase());
  106. setInterval(() => {
  107. if(location.href.indexOf("v2ex") == -1){
  108. return;
  109. }
  110.  
  111. document.querySelectorAll('article:not([scriptcheckkeyword="1"])').forEach(article => {
  112. article.setAttribute("scriptcheckkeyword","1"); //检查过要打标签避免重复检查
  113. var articleContent = article.textContent.toLowerCase();
  114. // 检查是否包含关键词
  115. var hasKeyword = ADKeywords.some(keyword => {
  116. if(keyword.includes("+")){
  117. return keyword.split("+").every(word=>articleContent.includes(word));
  118. } else {
  119. return articleContent.includes(keyword);
  120. }
  121. });
  122. // 如果包含关键词,则隐藏并添加属性
  123. if (hasKeyword) {
  124. article.setAttribute("style","height: 1px;width:1px; overflow: hidden;display:block;");
  125. }
  126. });
  127. }, 3000);//屏蔽带有关键字的内容
  128.  
  129. // 2.4 待增加
  130.  
  131. // 3 不重复运行
  132. // 3.1 弱化存档分类,隐藏未读数。
  133. ((setInterval_index,timecount=1)=>{setInterval_index=setInterval(()=>{
  134. if (document.querySelector('button[aria-label^="Mark 存档"')) {
  135. if (document.querySelector('button[aria-label^="Mark 存档"').style.opacity == "") {
  136. // 寻找存档文件夹的最上层元素,目的是设置透明,鼠标移动过去时取消透明
  137. var parEle = document.querySelector('button[aria-label^="Mark 存档"]');
  138. while (1) {
  139. parEle = parEle.parentElement;
  140. if(parEle.innerHTML.indexOf(">存档<") != -1){
  141. break;
  142. }
  143. }
  144.  
  145. //通过透明隐藏未读数
  146. parEle.onmouseover = () => {
  147. document.querySelector('button[aria-label^="Mark 存档"').style.opacity = "1";
  148. };
  149. parEle.onmouseout = () => {
  150. document.querySelector('button[aria-label^="Mark 存档"').style.opacity = "0.2";
  151. };
  152. parEle.onmouseout();
  153.  
  154. // 顺便隐藏掉returnALL类别的未读数
  155. document.querySelector('button[aria-label^="Mark returnALL"').style.display = "none";
  156.  
  157. clearInterval(setInterval_index);
  158. }
  159. }
  160.  
  161. if(timecount==30){clearInterval(setInterval_index);}timecount++;
  162. },2000);})(); //end 弱化存档分类
  163.  
  164. // 3.2 简化左侧 UI,无用导航菜单全部隐藏
  165. ((setInterval_index,timecount=1)=>{setInterval_index=setInterval(()=>{
  166. if(document.querySelector(".LeftnavSection")
  167. && document.querySelector(".LeftnavSection").parentElement.innerHTML.indexOf(">Integrations &amp; API<") != -1){
  168. setTimeout(() => {
  169. //判断最后一个菜单组已经加载,再演示一点时间,才开始隐藏不会报错。
  170. var menukeyword=[">Today<", ">Read Later<", ">Integrations &amp; API<"];
  171. document.querySelectorAll(".LeftnavSection").forEach(ele=>{
  172. menukeyword.forEach(word=>{
  173. if(ele.innerHTML.indexOf(word) != -1){
  174. ele.setAttribute("style","display:none;");
  175. ele.setAttribute("nemuhide","1");
  176. }
  177. });
  178. });
  179. //隐藏左侧上方的显示用户信息和子菜单
  180. document.querySelector(".LeftnavProfileItem").setAttribute("style","display:none;");
  181. document.querySelector(".LeftnavProfileItem").setAttribute("nemuhide","1");
  182. //增加显隐菜单组的操作功能,不知道为什么加上这个后界面会没反应,之后可以加在其他已有的元素上面
  183. document.querySelector(".LeftnavSection").parentElement.appendChild(document.createElement('div')).className='menu_showhide';
  184. document.querySelector(".menu_showhide").innerHTML="显示/隐藏菜单组";
  185. document.querySelector(".menu_showhide").addEventListener('click',()=>{
  186. document.querySelectorAll("div[nemuhide]").forEach(ele=>{
  187. ele.style.display=ele.style.display=="none"?"block":"none";
  188. })
  189. });
  190. }, 500); //延迟执行结束
  191.  
  192. clearInterval(setInterval_index);
  193. } //结束判断已准备好菜单
  194.  
  195. if (timecount == 120) { clearInterval(setInterval_index); } timecount++;
  196. },300);})();//end 优化左侧 UI
  197.  
  198. //3.3 消灭新特性提醒窗口(What's new,并且为漂浮状态)
  199. ((setInterval_index, timecount = 1) => {setInterval_index = setInterval(() => {
  200. if (document.querySelector(".AppDockedPopups")) {
  201. if (document.querySelector(".AppDockedPopups").innerHTML.indexOf("What's new") != -1) {
  202. document.querySelector(".AppDockedPopups").querySelector("button").click();
  203. }
  204. }
  205.  
  206. if (timecount == 200) { clearInterval(setInterval_index); } timecount++;
  207. }, 300);
  208. })(); //end
  209.  
  210. // 3.4 待增加
  211.  
  212. })(); //end all