開発者用拡張機能を公開するサイト

Cookie同意ポップアップをどけるJavascript

昨今はCookieの利用規制強化により、訪れると同意を求められるサイトが増えました。
それ自体はとても大切なことです。
法令を遵守するということ。

ですが、稀に実装しなくていいのに同意を求めてくるサイトがありませんかと。
例えばjimdoで作られたサイトとか。

あと必要なサイトでもページの半分ぐらいを占有して非常に邪魔なものなどありますね。
頻繁に訪れるサイトならいいのですが、ちょっと見ただけのサイトに邪魔なものが存在する場合
殆どの人はブラウザバックしますよね。

それは運営者側の判断に委ねられますが、少しだけ覗きたいユーザーからすればなんとか対策したいもの。
ということでそんなjavascriptを考えてみまして。

とりあえずrelative

ではまず検出する方法はどうするかと。
cookieの同意UIは基本的にページに常に表示されています。
つまり殆どの場合は「position:fixed」を使っています。

ではいったんfixedをrelativeに変えてやろうと。
let all_node = document.querySelectorAll('*');
for(let ani=0; ani<all_node.length; ani++){
	let computedStyle = window.getComputedStyle(all_node[ani]);
	if (computedStyle.position === 'fixed') {
		all_node[ani].style.position = 'relative';
	}
}

こうしてサイトの基本レイアウトを壊してみると面白い発見があるものですね。

殆どの場合、cookieの同意ポップアップはページの末尾に挿入されます。
しかしストリー○ファイター6のオフィシャルページはコードの先頭に挿入されます。
styleは
top: 100%;
transform: translate(-50%,-100%);

となっており、日本語にすれば「ページの高さ分 下げた後にボックスサイズ分 上に戻す」という描画方法。
これをrelativeにした場合ページ最上部に隙間ができ、ボックス自体は画面外に行きます。

他にメインコンテンツが「position:absolute」で作ってあるため
見た目上同意ボックスがメインより先に来てしまうものもあります。

話を戻して、cookie同意ボックスののfixedを弄りたいのですが、
これでは例えばヘッダーなども固定されてしまいます。

ではどうするかと考えたところ……無理やりやるしかありませんね。

条件分岐

let check_text = ['cookie','Cookie','クッキー'];
let all_node = document.querySelectorAll('*');
for(let ani=0; ani<all_node.length; ani++){
	let computedStyle = window.getComputedStyle(all_node[ani]);
	if (computedStyle.position === 'fixed') {
		let check_list = [
			check_class = all_node[ani].getAttribute('class'),
			check_id = all_node[ani].getAttribute('id'),
			check_inner = all_node[ani].innerText,
		];
		
		let change_flag = false;
		checkTextFor: for(let cht of check_text){
			for(let cci=0; cci<check_list.length; cci++){
				if(typeof check_list[cci] === 'string' && check_list[cci].indexOf(cht) !== -1){
					change_flag = true;
					break checkTextFor;
				}
			}
		}
		if(change_flag === true){
			all_node[ani].style.position = 'relative';
		}
	}
}

cookieの同意なんだから要素内に絶対cookieやクッキーって文字があるか
クラス名やIDにcookieって使ってるよね。

という力技の検出です。
なおforEachではなくforを使うのは個人的な趣味。
IEでforEach使った場合の非同期処理がどうのこうのしていたときの名残。

これで色々なサイトをテストしたところ、
jimdoで作られているサイトは殆どの場合で黒幕も追加されるのを確認しました。
同意か拒否をするまでそんなにサイト内を触られたくないですかと。
恐らくアナリティクスの検出のためにそうなってるのかもしれませんが。

そして黒幕はinnerTextがありませんし、クラス名もcookieがあったりなかったりします。
統一してくれませんかね。

最終的なstyleの設定

if(change_flag === true){
	all_node[ani].style.position = 'relative';
	all_node[ani].style.zIndex = '-1';

} else if(
	document.documentElement.clientHeight === all_node[ani].offsetHeight &&
	document.documentElement.clientWidth === all_node[ani].offsetWidth
){
	all_node[ani].style.display = 'none';
}

なので、クッキーの文字がなかった場合はその要素のサイズを確認。
要素のサイズとドキュメントの表示領域が同じ=widthとheightが100%と同値になっているもの、
それを黒幕と判断して display:none。
relativeじゃないのはサイト内に残したら他要素に被って選択できないモノがあったため。

z-index:-1 でもモノによっては大丈夫ですがケースバイケース。
何より同意しないために作ってるものではないので最終手段。

あとは拡張機能にするなりお気に入りJSにするなり煮るなり焼くなりお好きに。

余談

let all_node = document.querySelectorAll('*');
for(let ani=0; ani<all_node.length; ani++){
	let computedStyle = window.getComputedStyle(all_node[ani]);
	if (computedStyle.opacity === '0') {
		all_node[ani].style.opacity = '1';
		all_node[ani].style.translate = '0 0';
	}
}

スクロールに合わせて内容がふわふわ出てくるアレ
をどうにかしたかったのですが特に意味のなかったもの。

正確には表示しっぱなしにできるけど移動の条件が多すぎて対応しきれないもの。
あとカバーがスライドするものなどはどう判定しようかと。