阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 屏蔽广告:setInterval(() => document.querySelectorAll('.ad').forEach(el => el.remove()), 1000);

屏蔽广告:setInterval(() => document.querySelectorAll('.ad').forEach(el => el.remove()), 1000);

作者:陈川 阅读数:19198人阅读 分类: JavaScript

屏蔽广告的JavaScript实现

这段代码setInterval(() => document.querySelectorAll('.ad').forEach(el => el.remove()), 1000);展示了一个简单但有效的广告屏蔽方法。它通过定时查找并移除页面上的广告元素来实现广告屏蔽功能。

代码解析

让我们分解这段代码的工作原理:

setInterval(
  () => document.querySelectorAll('.ad').forEach(el => el.remove()), 
  1000
);
  1. document.querySelectorAll('.ad') - 选择所有class包含"ad"的DOM元素
  2. .forEach(el => el.remove()) - 遍历这些元素并逐个移除
  3. setInterval(..., 1000) - 每1000毫秒(1秒)执行一次上述操作

实际应用场景

这种技术常见于浏览器扩展或用户脚本中,用于屏蔽特定网站的广告。例如:

// 屏蔽视频网站的前贴片广告
setInterval(() => {
  const ads = document.querySelectorAll('.ad-container, .preroll, [class*="ad-"]');
  ads.forEach(ad => ad.style.display = 'none');
}, 500);

进阶实现

基础版本有几个可以改进的地方:

1. 性能优化

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

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

使用MutationObserver比setInterval更高效,它只在DOM变化时触发。

2. 支持多种广告选择器

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. 防止广告重新加载

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

实际案例

假设我们要屏蔽一个新闻网站的广告:

<!-- 页面HTML结构 -->
<div class="content">
  <article>...</article>
  <div class="ad-banner">广告内容</div>
  <article>...</article>
  <aside class="sidebar-ad">侧边栏广告</aside>
</div>

对应的屏蔽脚本:

// 屏蔽特定新闻网站的广告
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';
    });
  });
}

// 使用MutationObserver替代setInterval
const observer = new MutationObserver(blockNewsSiteAds);
observer.observe(document.body, { childList: true, subtree: true });

// 初始执行一次
blockNewsSiteAds();

注意事项

  1. 法律问题:某些国家/地区可能有法律限制广告屏蔽
  2. 网站功能:过度屏蔽可能影响网站正常功能
  3. 反屏蔽技术:许多网站会检测并阻止广告屏蔽器
// 检测并绕过简单的反广告屏蔽
if (window.adsBlocked) {
  Object.defineProperty(window, 'adsBlocked', { value: false });
}

更复杂的实现

对于现代网页应用,可能需要更复杂的方法:

// 拦截广告网络请求
const originalFetch = window.fetch;
window.fetch = async function(url, init) {
  if (url.includes('adserver') || url.includes('doubleclick')) {
    return Promise.reject(new Error('广告请求被屏蔽'));
  }
  return originalFetch(url, init);
};

// 屏蔽WebSocket广告
const originalWebSocket = window.WebSocket;
window.WebSocket = function(url) {
  if (url.includes('adservice')) {
    throw new Error('广告WebSocket被屏蔽');
  }
  return new originalWebSocket(url);
};

浏览器扩展中的应用

在Chrome扩展中实现广告屏蔽:

// 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());
  });
}

// 使用MutationObserver高效屏蔽
const observer = new MutationObserver(function(mutations) {
  mutations.forEach(() => blockAds());
});

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

// 初始执行
blockAds();

移动端考虑

移动网页广告可能有不同的结构:

// 移动端广告屏蔽
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);
    });
  });
}

// 使用requestAnimationFrame替代setInterval
function checkAndBlockAds() {
  blockMobileAds();
  requestAnimationFrame(checkAndBlockAds);
}

checkAndBlockAds();

处理动态加载的广告

对于异步加载的广告内容:

// 拦截动态广告插入
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;
};

性能监控与优化

// 广告屏蔽性能监控
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(`屏蔽了 ${ads.length} 个广告,总耗时 ${duration.toFixed(2)}ms`);
}

setInterval(blockAdsWithTracking, 2000);

与其他技术的结合

结合CSS屏蔽广告:

// 动态注入CSS屏蔽规则
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();

处理iframe广告

// 专门处理iframe广告
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('无法检查iframe src:', e);
    }
  });
}

// 监听iframe加载
document.addEventListener('DOMNodeInserted', function(e) {
  if (e.target.tagName === 'IFRAME') {
    blockIframeAds();
  }
});

setInterval(blockIframeAds, 1000);

广告屏蔽的进化

随着广告技术的发展,屏蔽方法也需要不断更新:

// 机器学习辅助广告识别(简化示例)
const adPatterns = {
  classNames: ['ad', 'ads', 'advert', 'advertisement'],
  idPatterns: /ad|banner|sponsor/i,
  sizePatterns: [
    { width: 728, height: 90 },   // 横幅
    { width: 300, height: 250 },  // 矩形
    { width: 160, height: 600 }   // 摩天大楼
  ]
};

function isLikelyAd(element) {
  // 检查class
  const classMatch = adPatterns.classNames.some(name => 
    element.classList.contains(name)
  );
  
  // 检查id
  const idMatch = element.id && adPatterns.idPatterns.test(element.id);
  
  // 检查尺寸
  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

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌