タブを切り替えて戻ってくると全面広告が表示されるやつについて


先日の記事「ブラウザの履歴を操作して「戻る」ボタンで広告を出すやつについて」にかなり大きな反響があったのだが、「タブを切り替えて戻ってくると全面広告が表示されるやつはどうなっているんだろう」という疑問を持っている人がけっこういるようなので、ちょっと説明する。こちらはPage Visibility API (ページ可視性 API) というのを使って実現している。

Page Visibility API – Web APIs | MDN

Page Visibility APIその本来の用途としては、以下のようなものが想定されている。

これは特に、文書が表示されていない時に不必要なタスクの実行を抑止することで、リソースを節約したり実行効率を上げたりするために特に有用です。

ページ可視性 API – Web API | MDN

例えば、ウェブアプリで動画を再生している場合、ユーザーがタブをバックグラウンドにした場合に動画を一時停止させ、ユーザーがこのタブに戻ったときに再生を再開させたりすることができます。ユーザーは動画の位置に迷うことがなく、動画の音声が新しく前景になったタブの音声を邪魔せず、ユーザーがその間に動画を見落とすことがなくなります。

ページ可視性 API – Web API | MDN

仕組みはとても単純で、visibilitychange イベントを拾い、非表示状態 (document.visibilityState=hidden) から表示状態 (document.visibilityState=visible) に変わったらオーバーレイを出している。

visibilitychange イベントのログを可視化し、非表示→表示に切り替わると「よーし全面広告出しちゃうぞ☆」というメッセージを追加するだけのデモページを用意してみた。タブの切り替えや最小化/復帰をすると色々表示される。

Page Visibility APIのシンプルなデモ

ソースはこんな感じ。

let wasHidden = false;
document.addEventListener('visibilitychange', function() {
    let log = document.getElementById('js_visibility_log');
    let li = document.createElement('li');
    li.textContent = `${new Date()} document.visibilityState=${document.visibilityState}`;
    log.appendChild(li);
    if (wasHidden && document.visibilityState === 'visible') {
        let adLi = document.createElement('li');
        adLi.textContent = 'よーし全面広告出しちゃうぞ☆';
        log.appendChild(adLi);
    }
    wasHidden = document.visibilityState === 'hidden'
});

こちらは、先日紹介した「戻る」ボタンと同じくらい鬱陶しい。後で読もうと思って別タブで開いたページが全部これだったりするとキレそうになる。けれど、ブラウザのUIの機能を乗っ取るような動きをするブラウザバック広告とは違い、あくまでページの「中」で起こることなので、「悪い」ではなく「ウザい」、つまり善悪よりも快不快というレイヤーの話だと思って我慢している。