Close Ads

Closes ads on LookMovie and removes specific reCAPTCHA, banner ads from the page

  1. // ==UserScript==
  2. // @name Close Ads
  3. // @namespace https://www.lookmovie2.to/
  4. // @version 0.6.3
  5. // @description Closes ads on LookMovie and removes specific reCAPTCHA, banner ads from the page
  6. // @author JJJ
  7. // @match https://www.lookmovie2.to/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=lookmovie2.to
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. // Exclude specific URL path
  17. if (window.location.href.includes('/threat-protection/')) {
  18. console.log('Ad closer script is disabled on this page.');
  19. return;
  20. }
  21.  
  22. const config = {
  23. closePlayerAdSelector: '.pre-init-ads--close',
  24. IPreferAdsSelector: 'button.no.stay-free[data-notify-html="buttonStayFree"]',
  25. notifyDivSelector: 'div.notifyjs-corner',
  26. bannerAdSelector: '.banner-become-affiliate',
  27. reCaptchaDivStyles: [
  28. 'background-color: rgb(255, 255, 255);',
  29. 'border: 1px solid rgb(204, 204, 204);',
  30. 'z-index: 2000000000;',
  31. 'position: absolute;'
  32. ],
  33. maxAttempts: 50,
  34. debounceTime: 200,
  35. continuousCheck: true,
  36. threatProtectionBaseUrl: 'https://www.lookmovie2.to/threat-protection/'
  37. };
  38.  
  39. let attempts = 0;
  40. let observer = null;
  41. let debounceTimeout = null;
  42.  
  43. // Function to interact with elements like clicking or removing
  44. const interactWithElement = (selector, action = 'remove') => {
  45. const element = document.querySelector(selector);
  46. if (element) {
  47. if (action === 'click') {
  48. element.click();
  49. console.log(`${selector} clicked`);
  50. } else {
  51. element.remove();
  52. console.log(`${selector} removed`);
  53. }
  54. return true;
  55. }
  56. return false;
  57. };
  58.  
  59. // Function to remove elements with specific inline styles
  60. const removeElementByStyles = (styles) => {
  61. const element = document.querySelector(`div[style*="${styles.join('"][style*="')}"]`);
  62. if (element) {
  63. element.remove();
  64. console.log('Element with matching styles removed');
  65. return true;
  66. }
  67. return false;
  68. };
  69.  
  70. // Function to handle ad closing and element interactions
  71. const handleAds = () => {
  72. try {
  73. // Prioritize removal of reCAPTCHA, notification, and banner ads
  74. if (removeElementByStyles(config.reCaptchaDivStyles) ||
  75. interactWithElement(config.notifyDivSelector) ||
  76. interactWithElement(config.bannerAdSelector) ||
  77. interactWithElement(config.closePlayerAdSelector, 'click') ||
  78. interactWithElement(config.IPreferAdsSelector, 'click')) {
  79. return true;
  80. }
  81. } catch (error) {
  82. console.error('Error while handling ads or buttons:', error);
  83. }
  84. return false;
  85. };
  86.  
  87. // Debounced function to handle ad removal during mutations
  88. const debouncedHandleAds = () => {
  89. clearTimeout(debounceTimeout);
  90. debounceTimeout = setTimeout(() => {
  91. if (handleAds()) {
  92. attempts = 0;
  93. } else {
  94. attempts++;
  95. }
  96.  
  97. if (!config.continuousCheck && attempts >= config.maxAttempts) {
  98. stopObserver();
  99. console.log('Ad handling process finished');
  100. }
  101. }, config.debounceTime);
  102. };
  103.  
  104. // Function to handle DOM mutations
  105. const handleMutations = () => {
  106. debouncedHandleAds();
  107. };
  108.  
  109. // Function to start the MutationObserver
  110. const startObserver = () => {
  111. if (observer) return;
  112.  
  113. observer = new MutationObserver(handleMutations);
  114. observer.observe(document.body, { childList: true, subtree: true });
  115. console.log('MutationObserver started');
  116. };
  117.  
  118. // Function to stop the MutationObserver
  119. const stopObserver = () => {
  120. if (observer) {
  121. observer.disconnect();
  122. observer = null;
  123. console.log('MutationObserver stopped');
  124. }
  125. };
  126.  
  127. // Function to initialize the ad closer
  128. const initAdCloser = () => {
  129. console.log('Ad closer initialized');
  130. if (handleAds()) {
  131. attempts = 0;
  132. }
  133.  
  134. startObserver();
  135. window.addEventListener('beforeunload', stopObserver);
  136. };
  137.  
  138. // Initialize once the document is ready
  139. if (document.readyState === 'complete' || document.readyState === 'interactive') {
  140. initAdCloser();
  141. } else {
  142. document.addEventListener('DOMContentLoaded', initAdCloser);
  143. }
  144.  
  145. setTimeout(initAdCloser, 1000);
  146.  
  147. // Polyfill for MutationObserver if not supported
  148. if (!window.MutationObserver) {
  149. window.MutationObserver = window.WebKitMutationObserver || window.MozMutationObserver || class {
  150. constructor(callback) {
  151. this.callback = callback;
  152. }
  153. observe() {
  154. console.warn('MutationObserver not supported by this browser.');
  155. }
  156. disconnect() { }
  157. };
  158. }
  159. })();

QingJ © 2025

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