맡고있는 프로젝트에서 [개인정보 취급방침 동의 페이지]를 만들게 되었다.

요즘 개인정보 취급방침을 안 읽는 사람이 많기 때문에(나 포함) 스크롤 시에 다음과 같이 동의 항목이 다음과 같이 열리도록 설정하는 것이 목적이다.

또한 동의함을 체크해야 가입 버튼이 활성화된다.

(아마도 기능 뿐 아니라 css도 함께 변경되도록 설정해놓았기 때문에 코드 분석에 어려움이 있을 수도 있다는 점 참고)
먼저 html 코드는 다음과 같다.
<div class="container d-flex flex-column" style="padding-top:1rem;">
<h5 style="color:black;">> 개인정보 취급방침 동의</h5>
<span style="font-size:1rem; color:blue;">* 아래 약관을 읽은 후 이용가능합니다.</span>
<div class="flex-center" style="padding-top:1rem;">
<textarea id="privacy_scroll" style="resize:none; width:100%; height:20rem; padding:0.5rem;" readonly>
-개인정보 취급방침 동의내용 작성하시면 됩니다.-
</textarea>
</div>
<form style="width:100%; text-align:center; margin:1rem 0;">
<p style="display:inline-block; margin-bottom:0;"><b>위 개인정보 수집에 대한 동의를 거부할 권리가 있으며, </b></p><p style="display:inline-block;"><b> 동의 거부시에는 회원가입이 제한 됩니다.</b></p>
<div><b>개인정보 취급방침에 동의하십니까?</b>
<div class="radio-wrapper">
<label id="privacy-text1" style="margin-left:0.5rem; color:#e3e3e3;">
<input type="radio" id="agree" name="privacy" value="agree" style="border:1px solid #e3e3e3; background-color:white;" disabled/> 동의함
</label>
<label id="privacy-text2" style="margin-left:0.5rem; color:#e3e3e3;">
<input type="radio" id="disagree" name="privacy" value="disagree" style="border:1px solid #e3e3e3; background-color:#e3e3e3;" checked="checked" disabled/> 동의안함
</label>
</div>
</div>
<input type="button" id="privacy_submit" onclick="alert('약관 동의 후 이용 가능합니다.');" value="가입하기" style="border:1px solid #e3e3e3; color:#e3e3e3;"/>
</form>
</div>
css 파일은 따로 만들지 않고, inline으로 작성하였다.
여기서 중요한 것은
textarea의 id : privacy_scroll
radio input(동의)의 id : agree
radio input(미동의)의 id : disagree
radio input의 name : privacy
submit button의 id : privacy_submit
라고 했을 때에
두 가지 경우가 있다.
(1) 스크롤을 모두 내렸을 때 체크가 가능하도록.
(2) 스크롤을 내리기만 해도 체크가 가능하도록.
개발자마다 원하는 방식을 선택하여 적용하면 된다.
js를 파악하기 전에 알아두어야 할 요소는 다음과 같다.
textarea의 전체 scroll할 수 있는 범위내에서의 scroll 위치를 나타내는 scrollTop,
스크롤되어 나타나는 부분까지의 높이를 나타내는 scrollHeight.
(1) 스크롤을 모두 내렸을 때 체크가 가능하도록 만드는 경우의 js
사실 구글링에 나와있는 자료 대부분은 scroll 시에 메뉴바 숨기기, 헤더 숨기기 등 scroll을 했는지 안했는지에 중점을 두고 코드가 작성되어 있었다.
scroll을 끝까지 했는지를 판단하려면,
scroll의 크기 + scrollTop > scrollHeight 로 조건을 만드는게 가장 이상적이지 않을까 싶은데, scroll의 크기를 구하는 것은 알지 못하여서 고민해보았다.
그래서 고민한 결과, 350정도의 여유를 주고,
scrollTop + 350 > scrollHeight의 조건을 주었더니 정상적으로 동작하게 되었다.
사실 정확하게 스크롤이 끝에 닿을 때를 측정하지는 못한다.
하지만, 거의 내려간 것을 확인 후에 변화하기 때문에 어느정도 비슷하게 구현한 셈이다.
$("#privacy_scroll").scroll(function(){
var scrollTop = $(this).scrollTop();
var scrollHeight = $(this).prop('scrollHeight');
if (scrollTop + 350 >= scrollHeight) {
$("#agree").removeAttr("disabled");
$("#disagree").removeAttr("disabled");
$("#privacy-text1").css("color","black");
$("#privacy-text2").css("color","black");
$("#privacy_submit").attr("disabled");
$("#agree").css("border", "1px solid black");
$("#disagree").css("border", "1px solid black");
// privacy라는 name을 가진 radio input의 check css 변경
$('input[name="privacy"]').each(function() {
var checked = $(this).prop('checked');
if(checked) {
$(this).css("background-color", "black");
} else {
$(this).css("background-color", "white");
}
});
}
});
(2) 스크롤을 내리기만 해도 체크가 가능하도록 만드는 경우의 js
이 경우는 너무 쉽다. scrollTop의 초기 위치가 0이기 때문에 0을 넘기만 하면 scroll이 움직인 것이기 때문이다.
$("#privacy_scroll").scroll(function(){
var scrollTop = $(this).scrollTop();
if (scrollTop > 0) {
$("#agree").removeAttr("disabled");
$("#disagree").removeAttr("disabled");
$("#privacy-text1").css("color","black");
$("#privacy-text2").css("color","black");
$("#privacy_submit").attr("disabled");
$("#agree").css("border", "1px solid black");
$("#disagree").css("border", "1px solid black");
// privacy라는 name을 가진 radio input의 check css 변경
$('input[name="privacy"]').each(function() {
var checked = $(this).prop('checked');
if(checked) {
$(this).css("background-color", "black");
} else {
$(this).css("background-color", "white");
}
});
}
});
위와 같이 코드를 짜게되면 두 경우 모두 사용가능해진다.