不快な広告に悩まされてませんか?
最近、ネットを見ていると「不快な広告」を散見します。筆者はちょっとHなアプリの紹介くらいなら許容範囲なのですが、暴力的な内容のモノは本当にNGなんですよね。あと脳破壊を示唆する漫画とか。
最初こそ「この広告を表示しない」とオプトアウト設定していたのですが、そういう措置をとれない広告もありますし、なんなら似たような別の広告が表示されることはあり得ます。
「AdBlockでも入れるか? いやでも、それは申し訳ないし……。まあ、我慢しよう」
そう思っていたのですが、ある時、筆者の堪忍袋の緒が切れる出来事が起きました。それは防虫剤の広告だったと思うのですが、寝ている人の周りにリアルなGが無数に集まっているデザインだったんです。もうね、思わず「うぎゃ!」と叫んでしまいました。なんでこんな広告を世に出してしまったのか理解に苦しみます。
「決めた、AdBlockerを入れよう! ……でもなあ、AdBlockerを入れたらサイト主に検知されるって聞くし……」
悩んだ末に私は「広告をブロックはせず、モザイクをかけるだけ」という拡張機能を作ることに決めました!
拡張機能の作り方
拡張機能を作るのは簡単です! まずフォルダを作ります。その中にmanifest.jsonとcontent.jsというファイルを作ります。manifest.jsonに以下のように記述します。
{
"name": "AdMosaic",
"version": "1.0.0",
"manifest_version": 3,
"description": "Add mosaic to ads",
"content_scripts": [{
"matches": ["*://*/*"],
"js": [
"content.js"
]
}]
}
name:拡張機能の名前
version:バージョン
manifest_version:3にする
description:拡張機能の説明
content_scripts:拡張機能の設定。配列。
matches:拡張機能が有効になるURL。今回は全サイトで有効化するから*://*/*
としている。
js:プログラムファイル名。今回はcontent.js
あとはchrome://extensions/
にアクセス、デベロッパー モードをオンにして「パッケージ化されていない拡張機能を読み込む」をクリックしたら追加できます。
もはや、メモ帳だけでも作れてしまうレベルで簡単ですね!!
広告の検出
広告は画像、もしくはiframeで実装されていることが多いみたいです。(たぶん)
そこでまずはiframe要素をすべて取得するコードを書きます。
const iframes = document.getElementsByTagName("iframe");
for(const iframe of iframes){
//広告か判断するコード
}
もちろん、広告以外にモザイクをかけてしまってはいけないので、広告かどうかを検知できるようにします。今回はtitleが存在するなら、それがadvertisementかadかad contentである物にモザイクをかけてみようと思います。
let title = iframe.getAttribute("title");
if(title !== null){
title = title.toLowerCase(); //すべて小文字にする
if(title == "advertisement" || title == "ad" || title == "ad content"){
hide(iframe); //広告にモザイクをかける
}
}
あとは広告にモザイクをかける「hide関数」を実装するだけです。
モザイクをかける
cssでモザイク(正確にはブラー)をかけるには以下のように書きます。
iframe.ad{
filter:blur(8px);
}
これをjsから設定すればいいわけですね!
コードは以下の通り。
function hide(ad){
ad.style.setProperty("opacity", "0.15", "important");
ad.style.setProperty("filter", "blur(8px)", "important");
}
広告を薄くして(opacityを0.15に設定)、ブラーフィルタをかけます(filterをblur(8px)に設定)。
なお、ad.style.opacity="0.15"だと消えないことがあるので、このようにimportant属性を付与して確実に半透明処理が行われるようにします。
以上機処理を0.1秒ごとに行う
広告の中には、ページ読み込み完了時点ではまだ読み込まれておらず、時間差で表示されるものがあります。そこで、「広告を検出したらブラーをかける」という処理を一定時間ごとに行う必要があります。ある関数を一定時間ごとに行うにはsetInterval
を使います。
function hideAds(){...中略...}
setInterval(hideAds, 100);//100msごとに関数を呼び出す。
全ソースコード
function hide(ad){
ad.style.setProperty("opacity", "0.15", "important");
ad.style.setProperty("filter", "blur(8px)", "important");
}
function hideAds(){
const imgs = document.getElementsByTagName("img");
for(const img of imgs){
if(img.alt == "Advertisement" || img.classList.contains("img_ad")){
hide(img);
}
}
const iframes = document.getElementsByTagName("iframe");
for(const iframe of iframes){
let id = iframe.getAttribute("id");
if(id !== null){
id = id.toLowerCase();
if(id.startsWith("aswift")){
hide(iframe);
continue;
}
}
let title = iframe.getAttribute("title");
if(title !== null){
title = title.toLowerCase();
if(title == "advertisement" || title == "ad" || title == "ad content"){
hide(iframe);
continue;
}
}
let aria_label = iframe.getAttribute("aria-label");
if(aria_label !== null){
aria_label = aria_label.toLowerCase();
if(aria_label == "advertisement" || aria_label == "ad" || aria_label == "ad content"){
hide(iframe);
continue;
}
}
}
}
hideAds();
setInterval(hideAds, 100);