Facebook Adblocker

Block all ads in Facebook News Feed.

当前为 2020-12-19 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Facebook Adblocker
  3. // @name:vi Facebook Adblocker
  4. // @namespace https://lelinhtinh.github.io
  5. // @description Block all ads in Facebook News Feed.
  6. // @description:vi Chặn quảng cáo được tài trợ trên trang chủ Facebook.
  7. // @version 1.3.0
  8. // @icon https://i.imgur.com/F8ai0jB.png
  9. // @author lelinhtinh
  10. // @oujs:author baivong
  11. // @license MIT; https://baivong.mit-license.org/license.txt
  12. // @match https://facebook.com/*
  13. // @match https://*.facebook.com/*
  14. // @noframes
  15. // @supportURL https://github.com/lelinhtinh/Userscript/issues
  16. // @run-at document-idle
  17. // @grant none
  18. // ==/UserScript==
  19.  
  20. (function () {
  21. 'use strict';
  22.  
  23. let adsCount = 0;
  24. let labelStore = [];
  25. let observerLabel;
  26. let observerStory;
  27. let observerHead;
  28. let isWatch;
  29.  
  30. const findAds = (wrapper) => {
  31. function removeAds() {
  32. if (!labelStore.length) return;
  33. const labelId = labelStore.pop();
  34.  
  35. const adsLabel = wrapper.querySelector('span[aria-labelledby="' + labelId + '"][class]');
  36. if (adsLabel === null) return;
  37.  
  38. const adsWrap = adsLabel.closest(isWatch ? 'div:not([class*=" "])' : '[data-pagelet^="FeedUnit"]');
  39. adsWrap.remove();
  40. // adsWrap.style.opacity = 0.1;
  41.  
  42. console.log(++adsCount, 'adsCount');
  43. removeAds();
  44. }
  45. removeAds();
  46.  
  47. const watchLabel = (labelHidden) => {
  48. if (observerLabel) return;
  49. observerLabel = new MutationObserver((mutationsList) => {
  50. for (let mutation of mutationsList) {
  51. if (
  52. mutation.type === 'attributes' &&
  53. mutation.attributeName === 'id' &&
  54. /(Được\s+tài\s+trợ|Sponsored)/i.test(mutation.target.textContent.trim())
  55. ) {
  56. labelStore.push(mutation.target.id);
  57. removeAds();
  58. }
  59. }
  60. });
  61. observerLabel.observe(labelHidden, {
  62. attributes: true,
  63. attributeFilter: ['id'],
  64. subtree: true,
  65. });
  66. };
  67.  
  68. const labelHidden = document.querySelector('[hidden="true"]');
  69. if (labelHidden === null) {
  70. if (observerLabel) {
  71. observerLabel.disconnect();
  72. observerLabel = null;
  73. }
  74. } else {
  75. watchLabel(labelHidden);
  76. }
  77. };
  78.  
  79. const init = () => {
  80. isWatch = location.pathname === '/watch';
  81. const newsFeed = document.querySelector('[role="feed"], [data-pagelet="MainFeed"]');
  82. if (newsFeed === null) return;
  83.  
  84. if (observerStory) observerStory.disconnect();
  85. observerStory = new MutationObserver((mutationsList) => {
  86. for (let mutation of mutationsList) {
  87. findAds(mutation.target);
  88. }
  89. });
  90. observerStory.observe(newsFeed, {
  91. attributes: false,
  92. childList: true,
  93. subtree: true,
  94. });
  95.  
  96. findAds(document);
  97. };
  98.  
  99. init();
  100.  
  101. if (observerHead) observerHead.disconnect();
  102. observerHead = new MutationObserver(init);
  103. observerHead.observe(document.head, {
  104. attributes: true,
  105. childList: true,
  106. subtree: true,
  107. });
  108.  
  109. (function (old) {
  110. window.history.pushState = function () {
  111. old.apply(window.history, arguments);
  112. init();
  113. };
  114. })(window.history.pushState);
  115. })();