【コピペで実装】Cookie使用同意のポップアップ3選

サイトを訪れたときに時々表示されるCookie使用同意のポップアップ。よくあるタイプのものを独自に作成してみました。
最小限のHTML/CSS, JavaScriptだけで構成しており、コピペで簡単に実装することができます。
※本ポップアップは、あくまでサイトがCookieを使用していることをユーザに伝える簡易的なものです。GDPRに準拠しているわけではないのでご注意ください。
はじめに:Cookie使用同意に関して
最近は以前に比べ、Cookieをはじめとする個人情報の扱いが世界的に厳しくなっています。
背景には、EUで2018年5月に施行されたGDPR(一般データ保護規則)の項目のうち、Cookieの利用同意に関する要件が厳格化したことがあるようです。その影響でGoogleさんが5000万ユーロの制裁金を科せられたとか…
現在、日本ではCookieの利用同意に関して明確なガイドラインが定められていない状態ですが、今後法律の改正に伴って同意が必要になる可能性もあります。
Cookieの使用同意に関する詳しい内容は、企業が取るべき対応策も含めて以下の記事で解説されているのでご参照ください。
HTML
今回作成したポップアップのHTMLです。
<div class="cookie-consent">
<div class="cookie-text">当サイトではCookieを使用します。Cookieの使用に関する詳細は「<a href="#privacy-policy">プライバシーポリシー</a>」をご覧ください。</div>
<div class="cookie-agree">OK</div>
</div>
お使いの環境に応じて、適切な場所に配置してください。よくわからない場合は、<body>
の直後に置くと間違いないと思います。
ノーマルタイプ
サイト下部に固定表示されるよくあるタイプです。
CSS
<style>
.cookie-consent {
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
bottom: 0;
width: 100%;
font-size: 12px;
color: #fff;
background: rgba(0,0,0,.7);
padding: 1.2em;
box-sizing: border-box;
visibility: hidden;
}
.cookie-consent.is-show {
visibility: visible;
}
.cookie-consent a {
color: #fff !important;
}
.cookie-agree {
color: #fff;
background: dodgerblue;
padding: .5em 1.5em;
}
.cookie-agree:hover {
cursor: pointer;
}
/* パッと消える */
.cc-hide1 {
display: none;
}
/* ゆっくり消える */
.cc-hide2 {
animation: hide 1s linear 0s;
animation-fill-mode: forwards;
}
@keyframes hide {
from {
opacity: 1;
}
to {
opacity: 0;
visibility: hidden;
}
}
/* メディアクエリ */
@media screen and (max-width: 600px) {
.cookie-consent {
flex-direction: column;
}
.cookie-text {
margin-bottom: 1em;
}
}
</style>
JavaScript
<script type='text/javascript'>
(function() {
const expire = 365; // 有効期限(日)
let cc = document.querySelector('.cookie-consent');
let ca = document.querySelector('.cookie-agree');
const flag = localStorage.getItem('popupFlag');
if (flag != null) {
const data = JSON.parse(flag);
if (data['value'] == 'true') {
popup();
} else {
const current = new Date();
if (current.getTime() > data['expire']) {
setWithExpiry('popupFlag', 'true', expire);
popup();
}
}
} else {
setWithExpiry('popupFlag', 'true', expire);
popup();
}
ca.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'false', expire);
});
function setWithExpiry(key, value, expire) {
const current = new Date();
expire = current.getTime() + expire * 24 * 3600 * 1000;
const item = {
value: value,
expire: expire
};
localStorage.setItem(key, JSON.stringify(item));
}
function popup() {
cc.classList.add('is-show');
}
}());
</script>
ボタンが押されたタイミングで非表示用のクラスを追加し、見えなくなるようにしています。.cc-hide1
はパッと消えて、.cc-hide2
はゆっくりと消えるのでお好きなほうを選んでください。
コメントを入れたexpire
部分で、OKボタンを押した後の非表示期間を設定できます(詳しくは後述)。
<head>
部分ではなく</body>
直前に置くようにしてください。
上から出るタイプ
ロード2秒後に上から降りてくるポップアップです。JavaScriptのsetTimeout(popup, 2000)
部分を変更することでお好きな時間に変更できます。n秒の場合、n*1000の値で指定してください。
CSS
<style>
.cookie-consent {
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
top: -100px;
left: calc(50% - 650px/2);
width: 650px;
font-size: 12px;
background: #fff;
padding: 1.2em;
box-sizing: border-box;
border: 1px solid #ddd;
visibility: visible;
transition: .5s;
}
.cookie-consent.is-show {
top: 30px;
}
.cookie-text {
width: 90%;
}
.cookie-agree {
color: #fff;
background: dodgerblue;
padding: .5em 1.5em;
}
.cookie-agree:hover {
cursor: pointer;
}
/* パッと消える */
.cc-hide1 {
display: none;
}
/* ゆっくり消える */
.cc-hide2 {
animation: hide 1s linear 0s;
animation-fill-mode: forwards;
}
@keyframes hide {
from {
opacity: 1;
}
to {
opacity: 0;
visibility: hidden;
}
}
/* メディアクエリ */
@media screen and (max-width: 650px) {
.cookie-consent {
flex-direction: column;
width: 300px;
left: calc(50% - 300px/2)
}
.cookie-text {
width: 100%;
margin-bottom: 1em;
}
}
</style>
JavaScript
<script type='text/javascript'>
(function() {
const expire = 365; // 有効期限(日)
let cc = document.querySelector('.cookie-consent');
let ca = document.querySelector('.cookie-agree');
const flag = localStorage.getItem('popupFlag');
if (flag != null) {
const data = JSON.parse(flag);
if (data['value'] == 'true') {
setTimeout(popup, 2000);
} else {
const current = new Date();
if (current.getTime() > data['expire']) {
setWithExpiry('popupFlag', 'true', expire);
setTimeout(popup, 2000);
}
}
} else {
setWithExpiry('popupFlag', 'true', expire);
setTimeout(popup, 2000);
}
ca.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'false', expire);
});
function setWithExpiry(key, value, expire) {
const current = new Date();
expire = current.getTime() + expire * 24 * 3600 * 1000;
const item = {
value: value,
expire: expire
};
localStorage.setItem(key, JSON.stringify(item));
}
function popup() {
cc.classList.add('is-show');
}
}());
</script>
下から出るタイプ
スクロールで下からひょっこり出てくるポップアップです。
CSS
<style>
.cookie-consent {
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
bottom: -200px;
left: calc(50% - 650px/2);
width: 650px;
font-size: 12px;
background: #fff;
padding: 1.2em;
box-sizing: border-box;
border: 1px solid #ddd;
visibility: visible;
transition: .5s;
}
.cookie-consent.is-show {
bottom: 30px;
}
.cookie-text {
width: 90%;
}
.cookie-agree {
color: #fff;
background: dodgerblue;
padding: .5em 1.5em;
}
.cookie-agree:hover {
cursor: pointer;
}
/* パッと消える */
.cc-hide1 {
display: none;
}
/* ゆっくり消える */
.cc-hide2 {
animation: hide 1s linear 0s;
animation-fill-mode: forwards;
}
@keyframes hide {
from {
opacity: 1;
}
to {
opacity: 0;
visibility: hidden;
}
}
/* メディアクエリ */
@media screen and (max-width: 650px) {
.cookie-consent {
flex-direction: column;
width: 300px;
left: calc(50% - 300px/2);
}
.cookie-text {
width: 100%;
margin-bottom: 1em;
}
}
</style>
JavaScript
<script type='text/javascript'>
(function() {
const expire = 365; // 有効期限(日)
let cc = document.querySelector('.cookie-consent');
let ca = document.querySelector('.cookie-agree');
const flag = localStorage.getItem('popupFlag');
if (flag != null) {
const data = JSON.parse(flag);
if (data['value'] == 'true') {
window.onscroll = () => {
if (window.pageYOffset) {
popup();
}
}
} else {
const current = new Date();
if (current.getTime() > data['expire']) {
setWithExpiry('popupFlag', 'true', expire);
window.onscroll = () => {
if (window.pageYOffset) {
popup();
}
}
}
}
} else {
setWithExpiry('popupFlag', 'true', expire);
window.onscroll = () => {
if (window.pageYOffset) {
popup();
}
}
}
ca.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'false', expire);
});
function setWithExpiry(key, value, expire) {
const current = new Date();
expire = current.getTime() + expire * 24 * 3600 * 1000;
const item = {
value: value,
expire: expire
};
localStorage.setItem(key, JSON.stringify(item));
}
function popup() {
cc.classList.add('is-show');
}
}());
</script>
ポップアップの仕様説明
当ポップアップは、表示・非表示の処理をJavaScriptのみで実現したものです。外部ライブラリ等は一切使用していないため、余計な通信が発生せず軽量なのが特徴。
スクリプト部分ではローカルストレージを利用したフラグ処理を行っており、OKボタンの押下状態がユーザの端末に記録されます。初めて読み込んだ場合やOKを押さなかった場合は表示され、1度OKを押した場合は以後表示されないようになっています。
コメントを頂き、OKボタンを押した後のポップアップの非表示期間を設定できるようにしました。expire
の部分を変更することで、任意の日数に設定することが可能です。
有効期限(デフォルトは1年間)を過ぎた場合、対象サイトを再訪問した際に状態がリセットされ、再びポップアップが表示されます。
ローカルストレージ(LocalStorage)に関して
「OKボタンを押して表示されなくなったけど、確認のためにもう一度表示させたい」というときは、ローカルストレージのキーを削除することで表示を復活させることができます。
F12キーを押し、開発者タブのメニューから「Application」→「Local Storage」を開き、対象サイトのキー一覧で右クリック→「Delete」で削除できます。

今回作成したポップアップでは、キーは"popupFlag"となっています。
同意した場合の処理追加例
同意ボタンを押した場合の例として、JavaScript側でCookieを発行する場合、ご紹介したコードを書き換えて以下のように処理を行うことができます。
// 同意ボタンを押した場合
ca.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'false', expire);
const date = new Date();
date.setTime(date.getTime() + 365 * 24 * 3600 * 1000); // Cookieの有効期限を設定
let expires = "; expires=" + date.toUTCString();
document.cookie = "cookie=true" + expires + "; path=/";
});
上のコードでは"cookie"に"true"を設定し、それを1年間保存します。
参考に、自社サイトにも導入を考えていますが、これって1回OK(許可)をクリックすれば、次回からは表示されない仕様になっていますでしょうか?
コメントありがとうございます。
実はもともと単純なポップアップ機能のみを提供しており、OKボタンの押下状態は保持しない仕様だったのですが、コメントをいただいて早速修正しました。
現在はOKボタンの押下状態を保持するようになっていますのでご安心ください。
参考にして挑戦してみます(^^
I'm glad you like it. The "super fast model" you mean is the cookie consent popup, right? Then, what can I do to share it the way you want? I have already shared my source code.
同意した後の表示させない期間を設定したいと思ったのですが、その機能をつけてはいただけませんか?
コメントありがとうございます。
同意後の非表示期間の設定に関して、スクリプトを修正し機能を実装しました。
ご確認よろしくお願いします。
>同意後の非表示期間の設定に関して、スクリプトを修正し機能を実装しました。
匿名になってしまってすみません、オノともうします。本当ですか!? ありがとうございます!! 感謝します!!
const expire = 365; // 有効期限(日)の部分を好きな数字に変更すればよいということですよね!? 「1」にして検証してみます。
ご確認ありがとうございます。
>const expire = 365; // 有効期限(日)の部分を好きな数字に変更すればよいということですよね!?
はい、その通りです。「1」に設定した場合、一度同意して1日後にサイトを訪れたときに再びポップアップが表示されるはずです。
自端末以外ではテストできていないので、検証のほう是非ともよろしくお願いします。
オノです。 上記「1」に設定したところ、1日後に表示されていました。
大変助かりました。ありがとうございます。
ご報告ありがとうございます。
お役に立てて良かったです。
もしかしたら、お使いのブラウザや端末に依存した問題かもしれません。
ご利用のブラウザと端末の情報、可能であれば問題のサイトURLを教えていただけますと幸いです。よろしくお願いいたします。
今それぞれの客先のサイトを導入予定があるので、
ログイン画面と組み合わせる場合もあります。例えば:ポップアップを押さないとログインできないというパターンもあり、その実装イメージはどう考えばいいでしょうか。
コメントありがとうございます。
「ポップアップを押さないとログインできない」というパターンの実装イメージですが、まずポップアップJavaScriptの
ca.addEventListener('click', () => {
...
});
内で同意済みを表すCookieをセットしておきます。
そしてログイン時のPHPで同意済みCookieの存在をチェックし、ある場合はログインさせる、ない場合はログインさせないという形にすれば良いと思います。
今回の件で なぜかIE11だと表示されないエラーがでておりまして
???
何がいけないのかもわからず
ヒントだけでも頂けたらと思い連絡しました
よろしくお願い致します
IEだとエラーが出るのは、JavaScriptの最新の記法に対応していないためです。
JavaScriptのコードで
const, let → var
() => → function()
に置き換えることで、正常に動作するはずです。
よくわからない場合は、こちらからお問い合わせください。入力されたメール宛てにIE用のスクリプトをお送りします。
修正してIEでも問題なく表示できました
助かりました
今後ともよろしくお願い致します
ご連絡ありがとうございます。
お役に立てて良かったです。
ありがとうございます。
質問なのですが、再度ポップアップを表示させるには開発者ツールでレジストリ削除が必要ということですが、
普段私が使用しているchromeの拡張機能、editthiscookieだとクッキーを削除してもフラグが残ってしまいます。
他のサイトだと消えるのですが、これはクッキーの保存場所が違うということでしょうか?
わかりにくければすいません。。。
ポップアップの表示・非表示のフラグはクッキーではなくローカルストレージで登録しています。
そのため、フラグを削除する際は開発者タブでローカルストレージのほうを確認してみてください。
よろしくお願いいたします。
最近のクッキーバナーでは「同意しない」というボタンも付いているものがありますが、「同意しない」ボタンのコードはどのようなものが良いでしょうか。もし宜しかったら、教えていただくと嬉しいです。よろしくお願いいたします。
コメントありがとうございます。
コードがお役に立っているようで良かったです。
「同意しない」ボタンですが、「同意」ボタンと同様に押下して一定期間ポップアップを消す仕様であれば、同意ボタンと同じコードを適用すれば良いかと思います。つまり、「同意しない」ボタンのクラスを.cookie-rejectとすると
let cr = document.querySelector('.cookie-reject');
cr.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'false', expire);
});
という風に。そして同意する場合に限りクッキーをセットする…という風にすれば、機能的に一番良い気がします。
大体わかり、組み込んでみて多分できたと思います。
この度は本当に、良い学びになりました。
ありがとうございました。
こちらページ遷移するたびにPOP UPが出ます。考えられる原因は何がありますでしょうか?
コメントありがとうございます。
「OK」ボタンを押した後でも、ページ遷移のたびにポップアップが表示されてしまうということでしょうか?
そうであれば、コードに手を加えている場合を除き、こちらでも原因がわかりかねます。
可能であれば、問題のサイトのURLを教えていただけないでしょうか?直接確かめれば原因が特定できるかもしれません。
コメントでお答えしにくい場合は、お問い合わせから個人的に情報を頂ければと思います。よろしくお願いいたします。
at popup (xxx.html:125:8)
at xxx.html:97:7
at xxx.html:127:2
上記のようなエラーが出て、ボタンをクリックしても何も動作しないという現象に悩んでいます。
※xxx.htmlというファイルのヘッダにcssもjsも直書きしています。
何か思い当たることがあれば教えていただけるとたいへん助かります。
よろしくお願いいたします。
ポップアップ本体のHTMLのクラス名の変更等はされていませんか?
エラー内容を見たところ、ポップアップHTMLの要素の参照が上手くできていないようです。
サイトに記載のあったソースをそのまま使ってテストしてみたのですが
以下のエラーとなり、ポップアップが上手く表示されません。
jsとcssは、以下のように外部ファイルにして読み込ませています。
consent.js
consent.css
> 以下の匿名の方の質問とおそらく同じ現象だと思いますが、
2022/07/22 11:49
私はサイトに掲載しているソースを丸々コピーしているためクラス名などは変更していません。
エラーとなる原因分かりますでしょうか?
consent.js:21 Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
at consent.js:21:6
at consent.js:39:2
consent.js:37 Uncaught TypeError: Cannot read properties of null (reading 'classList')
at popup (consent.js:37:8)
他の方がヘッダに直書きしているとのことなので、私もやってみましたがやはりエラー内容は変わりませんでした。なお、Chromeで試しています。
詳しい情報を頂きありがとうございます。
エラーの原因ですが、おそらくJavaScriptをヘッダに直書きしている(またはヘッダで外部ファイルを読み込んでいる)ためだと思います。JSのコードをヘッダ部分ではなく、</body>の直前に置いてみてください。
※ヘッダ部分は早い段階で処理されてしまうので、ポップアップHTMLのDOM構築よりも先にJSが読み込まれてしまい、正常に処理されていない可能性が高いです。
ありがとうございます!
ありがとうございます。
OKを押したら、今後同意文言は表示されないようにしたいのですが、
その場合は、単純に下記部分を削除すればいいのでしょうか。
const expire = 365; // 有効期限(日)
function setWithExpiry(key, value, expire) {
const current = new Date();
expire = current.getTime() + expire * 24 * 3600 * 1000;
const item = {
value: value,
expire: expire
};
localStorage.setItem(key, JSON.stringify(item));
}
よろしくお願いいたします。
コメントありがとうございます。
記事がお役に立っているようで嬉しいです。
ご質問の件ですが、OKボタンを押した後にポップアップを二度と表示させたくない場合は以下のif文部分を削除してください。
if (current.getTime() > data['expire']) {
...
}
上記コードを削除すると、有効期限経過後も再表示用の処理が行われないため、ポップアップが表示されなくなります。
お早いお返事ありがとうございます!!
if (current.getTime() > data['expire']) {
setWithExpiry('popupFlag', 'true', expire);
window.onscroll = function() {
if (window.pageYOffset) {
popup();
}
}
}
上記部分を削除しました。
ありがとうございましたm(__)m
表示など問題無く設置できたのですが
Cookieの動作確認はどのように行えば良いかご教示頂けますと幸いです。
コメントありがとうございます。
Cookieの確認に関してですが、まずはF12キーを押して開発者タブを開き、「Application」→「Cookies」で対象のウェブサイトをクリックします。
すると右側にCookieの情報が一覧表示されるので、そこで各データを確認できます。
参考画像
画像はChromeの場合ですが、他のブラウザでも同様に確認できると思います。
1点質問なのですがクッキーを保持する時間を30分にする場合はどうしたらよいでしょうか?
下記のように試してみたのですが反映されません。
expire = current.getTime() + expire * 24 * 3600 * 1000;
これを
expire = current.getTime() + expire * 1 * 60 * 1000;
にして
const expire = 365;
これを
const expire = 30;
にしてみましたが駄目です。
よろしければご教示ください。
問題のコードですが、クッキーではなくローカルストレージのほうの有効期限を30分にされていませんか?
クッキーをJavaScript側で発行する場合、追加処理例のようにクリック時の処理のスクリプトを置き換えてください。具体的には、元コードの
ca.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'false', expire);
});
の部分を、
// 同意ボタンを押した場合
ca.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'false', expire);
const date = new Date();
date.setTime(date.getTime() + 30 * 60 * 1000); // Cookieの有効期限を設定(30分)
let expires = "; expires=" + date.toUTCString();
document.cookie = "cookie=true" + expires + "; path=/";
});
に丸ごと置き換えてください。これで有効期限30分のクッキーが発行されるはずです。
教えていただいた情報でうまく出来ました!
本当に助かります。
有難うございました!
一点、お願いがございます。
「同意しない」ボタンを押下した場合の記述につきまして、
以前のコメントにあるように下記を追記しました。
// 同意しない
let cr = document.querySelector('.cookie-reject');
cr.addEventListener('click', () => {
cc.classList.add('cc-hide2');
setWithExpiry('popupFlag', 'false', expire);
});
そして同意する場合に限りクッキーをセットする。。とありますが
上記以外に必要な記述がありましたら教えていただけますと幸いです。
素人質問で申し訳ありません。
よろしくお願いいたします。
「同意する」「同意しない」ボタンの仕様の場合、上記の内容で大丈夫だと思います。よろしくお願いいたします。
ありがとうございます。
2点質問なのですが、
同意する、同意しないのコードですが、setWithExpiry('popupFlag', 'false', expire);
OKとNOでfalseの部分は変更して問題ないでしょうか?
//下記、OKボタンを押した際イベントハンドラ
ca.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'true', expire);
});
//下記、NOボタンを押した際イベントハンドラ
cr.addEventListener('click', () => {
cc.classList.add('cc-hide1');
setWithExpiry('popupFlag', 'false', expire);
});
また、ブラウザにIDがふられたかの確認で検証画面をみてみますと、
Local strageにはJSONからのデーターが帰ってきていますが、
cookiesの中には、自身のURLのみで空になります、実際にサーバーに上げて検証すればデータが出てくるのでしょうか?教えてください。
記事がお役に立ったようで嬉しいです。
ご質問の件に関して、回答は以下のようになります。
1.OK/NOボタンのコードに関して
>>OKとNOでfalseの部分は変更して問題ないでしょうか?
はい、問題ありません。ただし、
・trueの場合:サイトを訪れるたびにポップアップ表示
・falseの場合:有効期限(デフォルトで1年)が過ぎるまでポップアップ非表示
となっているため、ご提示いただいたコードの場合、trueとfalseの設定は逆のほうが良いかと思われます。
2.データについて
>>cookiesの中には、自身のURLのみで空になります
デフォルトのコードは、cookieにデータを保存する仕様になっていません。
OKボタンがクリックされた際にcookieを発行したい場合は、同意した場合の処理追加例を参考に処理を実装してください。
コメントを書き込む