【JavaScript】利用規約を全部読んだら、同意ボタンがアクティブになる
- #HTML
- #css
- #JavaScript
- #tips
こんにちは!
上毛印刷WEB制作担当のソーヤです。
今回は利用規約画面で使えるtipsを紹介します!
ちなみこういった利用規約って皆さんちゃんと読み込みますか?
実装例
利用規約
最後までお読みいただいた後、同意してください。
第1条(目的)
本利用規約(以下「本規約」)は、当サービスの利用条件を定めるものです。ユーザーの皆さまには、本規約に従って本サービスをご利用いただきます。
第2条(利用登録)
登録希望者が本規約に同意の上、所定の方法によって利用登録を申請し、当社がこれを承認することによって、利用登録が完了するものとします。当社は、利用登録の申請者に以下の事由があると判断した場合、利用登録の申請を承認しないことがあります。
第3条(禁止事項)
ユーザーは、本サービスの利用にあたり、以下の行為をしてはなりません。法令または公序良俗に違反する行為、犯罪行為に関連する行為、当社のサーバーまたはネットワークの機能を破壊したり、妨害したりする行為、当社のサービスの運営を妨害するおそれのある行為、他のユーザーに関する個人情報等を収集または蓄積する行為、不正アクセスをし、またはこれを試みる行為、その他、当社が不適切と判断する行為。
第4条(本サービスの提供の停止等)
当社は、以下のいずれかの事由があると判断した場合、ユーザーに事前に通知することなく本サービスの全部または一部の提供を停止または中断することができるものとします。本サービスにかかるコンピュータシステムの保守点検または更新を行う場合、地震、落雷、火災、停電または天災などの不可抗力により、本サービスの提供が困難となった場合。
第5条(免責事項)
当社の債務不履行責任は、当社の故意または重過失によらない場合には免責されるものとします。当社は、何らかの理由によって責任を負う場合にも、通常生じうる損害の範囲内かつ有料サービスにあっては代金額を上限として賠償する責任を負うものとします。
第6条(個人情報の取り扱い)
当社は、本サービスの利用によって取得する個人情報については、当社「プライバシーポリシー」に従い適切に取り扱うものとします。ユーザーは、本規約に同意することで、プライバシーポリシーにも同意したものとみなします。
第7条(規約の変更)
当社は必要と判断した場合には、ユーザーに通知することなくいつでも本規約を変更することができるものとします。なお、本規約の変更後、本サービスの利用を開始した場合には、当該ユーザーは変更後の規約に同意したものとみなします。
第8条(準拠法・裁判管轄)
本規約の解釈にあたっては、日本法を準拠法とします。本サービスに関して紛争が生じた場合には、当社の本店所在地を管轄する裁判所を専属的合意管轄とします。
下までスクロールしてください
HTML例
<div class="card">
<div class="card-header">
<h1>利用規約</h1>
<p>最後までお読みいただいた後、同意してください。</p>
</div>
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<div class="scroll-wrap">
<div class="terms-box" id="termsBox">
<h2>第1条(目的)</h2>
<p>本利用規約(以下「本規約」)は、当サービスの利用条件を定めるものです。ユーザーの皆さまには、本規約に従って本サービスをご利用いただきます。</p>
<h2>第2条(利用登録)</h2>
<p>登録希望者が本規約に同意の上、所定の方法によって利用登録を申請し、当社がこれを承認することによって、利用登録が完了するものとします。当社は、利用登録の申請者に以下の事由があると判断した場合、利用登録の申請を承認しないことがあります。</p>
<h2>第3条(禁止事項)</h2>
<p>ユーザーは、本サービスの利用にあたり、以下の行為をしてはなりません。法令または公序良俗に違反する行為、犯罪行為に関連する行為、当社のサーバーまたはネットワークの機能を破壊したり、妨害したりする行為、当社のサービスの運営を妨害するおそれのある行為、他のユーザーに関する個人情報等を収集または蓄積する行為、不正アクセスをし、またはこれを試みる行為、その他、当社が不適切と判断する行為。</p>
<h2>第4条(本サービスの提供の停止等)</h2>
<p>当社は、以下のいずれかの事由があると判断した場合、ユーザーに事前に通知することなく本サービスの全部または一部の提供を停止または中断することができるものとします。本サービスにかかるコンピュータシステムの保守点検または更新を行う場合、地震、落雷、火災、停電または天災などの不可抗力により、本サービスの提供が困難となった場合。</p>
<h2>第5条(免責事項)</h2>
<p>当社の債務不履行責任は、当社の故意または重過失によらない場合には免責されるものとします。当社は、何らかの理由によって責任を負う場合にも、通常生じうる損害の範囲内かつ有料サービスにあっては代金額を上限として賠償する責任を負うものとします。</p>
<h2>第6条(個人情報の取り扱い)</h2>
<p>当社は、本サービスの利用によって取得する個人情報については、当社「プライバシーポリシー」に従い適切に取り扱うものとします。ユーザーは、本規約に同意することで、プライバシーポリシーにも同意したものとみなします。</p>
<h2>第7条(規約の変更)</h2>
<p>当社は必要と判断した場合には、ユーザーに通知することなくいつでも本規約を変更することができるものとします。なお、本規約の変更後、本サービスの利用を開始した場合には、当該ユーザーは変更後の規約に同意したものとみなします。</p>
<h2>第8条(準拠法・裁判管轄)</h2>
<p>本規約の解釈にあたっては、日本法を準拠法とします。本サービスに関して紛争が生じた場合には、当社の本店所在地を管轄する裁判所を専属的合意管轄とします。</p>
</div>
<div class="scroll-fade" id="scrollFade"></div>
</div>
<div class="scroll-hint" id="scrollHint">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
<path d="M7 2v10M3 8l4 4 4-4" stroke="#6e6e73" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
下までスクロールしてください
</div>
<div class="card-footer">
<div class="checkbox-row" id="checkboxRow">
<input type="checkbox" id="agreeCheck" disabled>
<label for="agreeCheck">利用規約をすべて読み、内容に同意します</label>
</div>
<button class="btn" id="agreeBtn" disabled>同意して続ける</button>
</div>
</div>CSS例
.card {
background: #f8f8f8;
border-radius: 0;
width: 100%;
max-width: 560px;
overflow: hidden;
margin: auto;
}
.card-header {
padding: 24px 28px 16px;
border-bottom: 1px solid #e5e5ea;
}
.card-header h1 {
font-size: 1.1rem;
font-weight: 700;
color: #1c1c1e;
}
.card-header p {
font-size: 0.82rem;
color: #6e6e73;
margin-top: 4px;
}
.scroll-wrap {
position: relative;
margin: 0;
}
.terms-box {
height: 280px;
overflow-y: auto;
padding: 20px 28px;
font-size: 0.85rem;
line-height: 1.8;
color: #3a3a3c;
border-bottom: 1px solid #e5e5ea;
scroll-behavior: smooth;
}
.terms-box::-webkit-scrollbar {
width: 6px;
}
.terms-box::-webkit-scrollbar-track {
background: #f4f4f6;
}
.terms-box::-webkit-scrollbar-thumb {
background: #c7c7cc;
border-radius: 3px;
}
.terms-box h2 {
font-size: 0.88rem;
font-weight: 700;
margin: 20px 0 8px;
color: #1c1c1e;
}
.terms-box h2:first-child {
margin-top: 0;
}
.scroll-fade {
position: absolute;
bottom: 0; left: 0; right: 0;
height: 56px;
background: linear-gradient(transparent, rgba(255,255,255,0.95));
pointer-events: none;
transition: opacity 0.3s;
}
.scroll-fade.hidden {
opacity: 0;
}
.scroll-hint {
text-align: center;
font-size: 0.75rem;
color: #6e6e73;
padding: 10px 0 6px;
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
transition: opacity 0.3s;
}
.scroll-hint.hidden {
opacity: 0;
pointer-events: none;
}
.scroll-hint svg {
animation: bounce 1.2s infinite;
}
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(3px);
}
}
.card-footer {
padding: 20px 28px 24px;
}
.checkbox-row {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 16px;
opacity: 0.4;
transition: opacity 0.3s;
cursor: not-allowed;
}
.checkbox-row.active {
opacity: 1;
cursor: pointer;
}
.checkbox-row input[type="checkbox"] {
width: 18px;
height: 18px;
accent-color: #007aff;
cursor: inherit;
flex-shrink: 0;
}
.checkbox-row label {
font-size: 0.85rem;
color: #3a3a3c;
cursor: inherit;
user-select: none;
}
.btn {
width: 100%;
padding: 13px;
border: none;
border-radius: 8px;
font-size: 0.95rem;
font-weight: 700;
cursor: not-allowed;
background: #c7c7cc;
color: #fff;
transition: background 0.25s, transform 0.1s;
letter-spacing: 0.02em;
}
.btn.active {
background: #007aff;
cursor: pointer;
}
.btn.active:hover {
background: #0062cc;
}
.btn.active:active {
transform: scale(0.98);
}
.progress-bar {
height: 3px;
background: #e5e5ea;
position: relative;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: #007aff;
width: 0%;
transition: width 0.15s;
}JavaScript例
const termsBox = document.getElementById('termsBox');
const scrollFade = document.getElementById('scrollFade');
const scrollHint = document.getElementById('scrollHint');
const progressFill= document.getElementById('progressFill');
const checkboxRow = document.getElementById('checkboxRow');
const agreeCheck = document.getElementById('agreeCheck');
const agreeBtn = document.getElementById('agreeBtn');
let hasReadAll = false;
function updateScroll() {
const { scrollTop, scrollHeight, clientHeight } = termsBox;
const scrollable = scrollHeight - clientHeight;
const ratio = scrollable > 0 ? scrollTop / scrollable : 1;
progressFill.style.width = Math.min(ratio * 100, 100) + '%';
if (ratio >= 0.98 && !hasReadAll) {
hasReadAll = true;
scrollFade.classList.add('hidden');
scrollHint.classList.add('hidden');
checkboxRow.classList.add('active');
agreeCheck.disabled = false;
}
}
termsBox.addEventListener('scroll', updateScroll);
updateScroll();
agreeCheck.addEventListener('change', () => {
if (agreeCheck.checked) {
agreeBtn.classList.add('active');
agreeBtn.disabled = false;
} else {
agreeBtn.classList.remove('active');
agreeBtn.disabled = true;
}
});
agreeBtn.addEventListener('click', () => {
if (!agreeCheck.checked) return;
alert('同意が完了しました!');
});まとめ
今回もjQueryではなく、Vanilla.jsで実装してみました。
コピペしてガンガン使ってください!
この記事に対するご意見・ご感想・ご質問等ありましたら、
ぜひ下記フォームにてお送りください。