阿里云主机折上折
  • 微信号
Current Site:Index > Block ads: setInterval(() => document.querySelectorAll('.ad').forEach(el => el.remove()), 1000);

Block ads: setInterval(() => document.querySelectorAll('.ad').forEach(el => el.remove()), 1000);

Author:Chuan Chen 阅读数:19199人阅读 分类: JavaScript

JavaScript Implementation for Ad Blocking

This code setInterval(() => document.querySelectorAll('.ad').forEach(el => el.remove()), 1000); demonstrates a simple yet effective method for ad blocking. It works by periodically finding and removing ad elements from the page.

Code Analysis

Let's break down how this code works:

setInterval(
  () => document.querySelectorAll('.ad').forEach(el => el.remove()), 
  1000
);
  1. document.querySelectorAll('.ad') - Selects all DOM elements with the class "ad"
  2. .forEach(el => el.remove()) - Iterates through these elements and removes each one
  3. setInterval(..., 1000) - Executes the above operation every 1000 milliseconds (1 second)

Practical Applications

This technique is commonly used in browser extensions or user scripts to block ads on specific websites. For example:

// Block pre-roll ads on video sites
setInterval(() => {
  const ads = document.querySelectorAll('.ad-container, .preroll, [class*="ad-"]');
  ads.forEach(ad => ad.style.display = 'none');
}, 500);

Advanced Implementations

The basic version has several areas for improvement:

1. Performance Optimization

let observer = new MutationObserver(mutations => {
  document.querySelectorAll('.ad').forEach(el => el.remove());
});

observer.observe(document.body, {
  childList: true,
  subtree: true
});

Using MutationObserver is more efficient than setInterval as it only triggers when DOM changes occur.

2. Supporting Multiple Ad Selectors

const adSelectors = [
  '.ad',
  '.advertisement',
  '[id*="ad"]',
  '[class*="ad"]',
  'iframe[src*="ads"]'
];

function removeAds() {
  adSelectors.forEach(selector => {
    document.querySelectorAll(selector).forEach(el => el.remove());
  });
}

setInterval(removeAds, 1000);

3. Preventing Ad Reloading

const originalAppendChild = Element.prototype.appendChild;
Element.prototype.appendChild = function(node) {
  if (node.classList && node.classList.contains('ad')) {
    return node;
  }
  return originalAppendChild.apply(this, arguments);
};

Real-World Example

Suppose we want to block ads on a news website:

<!-- Page HTML structure -->
<div class="content">
  <article>...</article>
  <div class="ad-banner">Ad content</div>
  <article>...</article>
  <aside class="sidebar-ad">Sidebar ad</aside>
</div>

Corresponding blocking script:

// Block ads on specific news sites
const newsSiteAdSelectors = [
  '.ad-banner',
  '.sidebar-ad',
  '.article-sponsor',
  '.recommend-ad'
];

function blockNewsSiteAds() {
  newsSiteAdSelectors.forEach(selector => {
    document.querySelectorAll(selector).forEach(el => {
      el.innerHTML = '';
      el.style.height = '0';
      el.style.overflow = 'hidden';
    });
  });
}

// Use MutationObserver instead of setInterval
const observer = new MutationObserver(blockNewsSiteAds);
observer.observe(document.body, { childList: true, subtree: true });

// Initial execution
blockNewsSiteAds();

Considerations

  1. Legal Issues: Some countries/regions may have legal restrictions on ad blocking
  2. Website Functionality: Excessive blocking may affect normal website functionality
  3. Anti-Blocking Techniques: Many websites detect and prevent ad blockers
// Detect and bypass simple anti-ad-blocking
if (window.adsBlocked) {
  Object.defineProperty(window, 'adsBlocked', { value: false });
}

More Complex Implementations

For modern web applications, more sophisticated methods may be needed:

// Intercept ad network requests
const originalFetch = window.fetch;
window.fetch = async function(url, init) {
  if (url.includes('adserver') || url.includes('doubleclick')) {
    return Promise.reject(new Error('Ad request blocked'));
  }
  return originalFetch(url, init);
};

// Block WebSocket ads
const originalWebSocket = window.WebSocket;
window.WebSocket = function(url) {
  if (url.includes('adservice')) {
    throw new Error('Ad WebSocket blocked');
  }
  return new originalWebSocket(url);
};

Application in Browser Extensions

Implementing ad blocking in Chrome extensions:

// background.js
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    if (details.url.match(/ads?\.|adserver|doubleclick/)) {
      return { cancel: true };
    }
  },
  { urls: ["<all_urls>"] },
  ["blocking"]
);

// content.js
function blockAds() {
  const selectors = [
    'div[class*="ad"]',
    'iframe[src*="ads"]',
    'img[src*="banner"]'
  ];
  
  selectors.forEach(selector => {
    document.querySelectorAll(selector).forEach(el => el.remove());
  });
}

// Use MutationObserver for efficient blocking
const observer = new MutationObserver(function(mutations) {
  mutations.forEach(() => blockAds());
});

observer.observe(document, {
  childList: true,
  subtree: true
});

// Initial execution
blockAds();

Mobile Considerations

Mobile web ads may have different structures:

// Mobile ad blocking
const mobileAdSelectors = [
  '.mobile-ad',
  '.ad-mrec',
  '[data-ad-type]',
  '[data-ad-unit]',
  'amp-ad'
];

function blockMobileAds() {
  mobileAdSelectors.forEach(selector => {
    document.querySelectorAll(selector).forEach(el => {
      el.parentNode?.removeChild(el);
    });
  });
}

// Use requestAnimationFrame instead of setInterval
function checkAndBlockAds() {
  blockMobileAds();
  requestAnimationFrame(checkAndBlockAds);
}

checkAndBlockAds();

Handling Dynamically Loaded Ads

For asynchronously loaded ad content:

// Intercept dynamic ad insertion
const adKeywords = ['ad', 'banner', 'sponsor', 'promo'];

function isAdElement(element) {
  const attributes = Array.from(element.attributes);
  return attributes.some(attr => 
    adKeywords.some(keyword => 
      attr.name.includes(keyword) || attr.value.includes(keyword)
    )
  );
}

const originalCreateElement = Document.prototype.createElement;
Document.prototype.createElement = function(tagName, options) {
  const element = originalCreateElement.call(this, tagName, options);
  
  if (isAdElement(element)) {
    element.dataset.adBlocked = 'true';
    return element;
  }
  
  return element;
};

Performance Monitoring and Optimization

// Ad blocking performance monitoring
let totalAdsBlocked = 0;
const performanceEntries = [];

function blockAdsWithTracking() {
  const startTime = performance.now();
  const ads = document.querySelectorAll('.ad, [class*="ad-"]');
  
  ads.forEach(ad => {
    if (!ad.dataset.adBlocked) {
      ad.remove();
      totalAdsBlocked++;
      ad.dataset.adBlocked = 'true';
    }
  });
  
  const duration = performance.now() - startTime;
  performanceEntries.push({
    timestamp: Date.now(),
    adsBlocked: ads.length,
    duration
  });
  
  console.log(`Blocked ${ads.length} ads, total time ${duration.toFixed(2)}ms`);
}

setInterval(blockAdsWithTracking, 2000);

Integration with Other Technologies

Combining with CSS for ad blocking:

// Dynamically inject CSS blocking rules
function injectAdBlockingCSS() {
  const style = document.createElement('style');
  style.textContent = `
    .ad, [class*="ad-"], [id*="ad"], 
    .advertisement, .banner, 
    iframe[src*="ads"], [data-ad] {
      display: none !important;
      visibility: hidden !important;
      height: 0 !important;
      width: 0 !important;
      padding: 0 !important;
      margin: 0 !important;
      border: none !important;
    }
  `;
  document.head.appendChild(style);
}

injectAdBlockingCSS();

Handling Iframe Ads

// Specifically handle iframe ads
function blockIframeAds() {
  document.querySelectorAll('iframe').forEach(iframe => {
    try {
      const src = iframe.src || '';
      if (src.includes('ads') || 
          src.includes('banner') || 
          src.includes('doubleclick')) {
        iframe.remove();
      }
    } catch (e) {
      console.warn('Cannot check iframe src:', e);
    }
  });
}

// Listen for iframe loading
document.addEventListener('DOMNodeInserted', function(e) {
  if (e.target.tagName === 'IFRAME') {
    blockIframeAds();
  }
});

setInterval(blockIframeAds, 1000);

Evolution of Ad Blocking

As ad technology advances, blocking methods need continuous updates:

// Machine learning-assisted ad identification (simplified example)
const adPatterns = {
  classNames: ['ad', 'ads', 'advert', 'advertisement'],
  idPatterns: /ad|banner|sponsor/i,
  sizePatterns: [
    { width: 728, height: 90 },   // Banner
    { width: 300, height: 250 },  // Rectangle
    { width: 160, height: 600 }   // Skyscraper
  ]
};

function isLikelyAd(element) {
  // Check class
  const classMatch = adPatterns.classNames.some(name => 
    element.classList.contains(name)
  );
  
  // Check id
  const idMatch = element.id && adPatterns.idPatterns.test(element.id);
  
  // Check dimensions
  const rect = element.getBoundingClientRect();
  const sizeMatch = adPatterns.sizePatterns.some(size => 
    Math.abs(rect.width - size.width) < 5 && 
    Math.abs(rect.height - size.height) < 5
  );
  
  return classMatch || idMatch || sizeMatch;
}

function smartAdBlock() {
  document.querySelectorAll('div, section, aside').forEach(el => {
    if (isLikelyAd(el)) {
      el.style.display = 'none';
      el.dataset.adBlocked = 'true';
    }
  });
}

setInterval(smartAdBlock, 1500);

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.